Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAras Pranckevicius <aras@nesnausk.org>2022-05-12 13:48:55 +0300
committerAras Pranckevicius <aras@nesnausk.org>2022-05-12 13:49:05 +0300
commit9757b4efb12e0fba21735fa7960148e6a7b67bb2 (patch)
treef10d73e9d57b840fe20131a069b75171d6d2fe17 /source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh
parent207b0c2a0f792375ea7a3087823af41621ececd2 (diff)
OBJ: improve new importer file parsing performance on windows
The OBJ parser was primarily using StringRef for convenience, with functions like "skip whitespace" or "parse a number" taking an input stringref, representing an input line, and returning a new stringref, representing the remainder of the line. This is convenient, but does more work than strictly needed -- while parsing, only the "beginning" of the line ever changes by moving forward; the end of the line always stays the same. We can change the code to take a pair of pointers (begin of line, end of line) as input, and make the functions return the new begin of line pointer. This makes the return value neatly fit into a processor register, which StringRef did not. On Windows, this does result in non-trivial speedups in the actual OBJ file parsing part, due to Windows calling convention where return values larger than 64 bits are returned via memory. Does not measurably affect performance on Mac/Linux, because the calling convention there uses a pair of 64-bit registers to return a StringRef. End-to-end times of importing several test files, on Windows (VS2022 build, Ryzen 5950X): - Monkey subdivided to level 6, no normals (220MB file): 1.25s -> 0.85s - Rungholt minecraft level (270MB file): 7.0s -> 5.8s - Blender 3 splash scene (2.4GB file): 49.1s -> 45.5s The full import process has a lot of other overhead besides actual OBJ file parsing (mostly creating actual blender objects out of parsed data). In pure parsing, in the monkey test scene above, the parsing part goes 1.0s -> 0.6s. Reviewed By: Howard Trickey Differential Revision: https://developer.blender.org/D14936
Diffstat (limited to 'source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh')
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh30
1 files changed, 20 insertions, 10 deletions
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh
index 532224569ac..3f428b1ab5c 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh
+++ b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh
@@ -9,6 +9,14 @@
* The utilities are not directly usable by other formats, since
* they treat backslash (\) as a whitespace character (OBJ format
* allows backslashes to function as a line-continuation character).
+ *
+ * Many of these functions take two pointers (p, end) indicating
+ * which part of a string to operate on, and return a possibly
+ * changed new start of the string. They could be taking a StringRef
+ * as input and returning a new StringRef, but this is a hot path
+ * in OBJ parsing, and the StringRef approach does lose performance
+ * (mostly due to return of StringRef being two register-size values
+ * instead of just one pointer).
*/
namespace blender::io::obj {
@@ -26,16 +34,16 @@ namespace blender::io::obj {
StringRef read_next_line(StringRef &buffer);
/**
- * Drop leading white-space from a StringRef.
+ * Drop leading white-space from a string part.
* Note that backslash character is considered white-space.
*/
-StringRef drop_whitespace(StringRef str);
+const char *drop_whitespace(const char *p, const char *end);
/**
- * Drop leading non-white-space from a StringRef.
+ * Drop leading non-white-space from a string part.
* Note that backslash character is considered white-space.
*/
-StringRef drop_non_whitespace(StringRef str);
+const char *drop_non_whitespace(const char *p, const char *end);
/**
* Parse an integer from an input string.
@@ -44,9 +52,10 @@ StringRef drop_non_whitespace(StringRef str);
* number can't be parsed (invalid syntax, out of range),
* `fallback` value is stored instead.
*
- * Returns the remainder of the input string after parsing.
+ * Returns the start of remainder of the input string after parsing.
*/
-StringRef parse_int(StringRef str, int fallback, int &dst, bool skip_space = true);
+const char *parse_int(
+ const char *p, const char *end, int fallback, int &dst, bool skip_space = true);
/**
* Parse a float from an input string.
@@ -55,9 +64,10 @@ StringRef parse_int(StringRef str, int fallback, int &dst, bool skip_space = tru
* number can't be parsed (invalid syntax, out of range),
* `fallback` value is stored instead.
*
- * Returns the remainder of the input string after parsing.
+ * Returns the start of remainder of the input string after parsing.
*/
-StringRef parse_float(StringRef str, float fallback, float &dst, bool skip_space = true);
+const char *parse_float(
+ const char *p, const char *end, float fallback, float &dst, bool skip_space = true);
/**
* Parse a number of white-space separated floats from an input string.
@@ -65,8 +75,8 @@ StringRef parse_float(StringRef str, float fallback, float &dst, bool skip_space
* number can't be parsed (invalid syntax, out of range),
* `fallback` value is stored instead.
*
- * Returns the remainder of the input string after parsing.
+ * Returns the start of remainder of the input string after parsing.
*/
-StringRef parse_floats(StringRef str, float fallback, float *dst, int count);
+const char *parse_floats(const char *p, const char *end, float fallback, float *dst, int count);
} // namespace blender::io::obj