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.cc
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.cc')
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc51
1 files changed, 26 insertions, 25 deletions
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc
index c60306c8375..ffafbe41d0f 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc
@@ -38,62 +38,63 @@ static bool is_whitespace(char c)
return c <= ' ' || c == '\\';
}
-StringRef drop_whitespace(StringRef str)
+const char *drop_whitespace(const char *p, const char *end)
{
- while (!str.is_empty() && is_whitespace(str[0])) {
- str = str.drop_prefix(1);
+ while (p < end && is_whitespace(*p)) {
+ ++p;
}
- return str;
+ return p;
}
-StringRef drop_non_whitespace(StringRef str)
+const char *drop_non_whitespace(const char *p, const char *end)
{
- while (!str.is_empty() && !is_whitespace(str[0])) {
- str = str.drop_prefix(1);
+ while (p < end && !is_whitespace(*p)) {
+ ++p;
}
- return str;
+ return p;
}
-static StringRef drop_plus(StringRef str)
+static const char *drop_plus(const char *p, const char *end)
{
- if (!str.is_empty() && str[0] == '+') {
- str = str.drop_prefix(1);
+ if (p < end && *p == '+') {
+ ++p;
}
- return str;
+ return p;
}
-StringRef parse_float(StringRef str, float fallback, float &dst, bool skip_space)
+const char *parse_float(
+ const char *p, const char *end, float fallback, float &dst, bool skip_space)
{
if (skip_space) {
- str = drop_whitespace(str);
+ p = drop_whitespace(p, end);
}
- str = drop_plus(str);
- fast_float::from_chars_result res = fast_float::from_chars(str.begin(), str.end(), dst);
+ p = drop_plus(p, end);
+ fast_float::from_chars_result res = fast_float::from_chars(p, end, dst);
if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
dst = fallback;
}
- return StringRef(res.ptr, str.end());
+ return res.ptr;
}
-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)
{
for (int i = 0; i < count; ++i) {
- str = parse_float(str, fallback, dst[i]);
+ p = parse_float(p, end, fallback, dst[i]);
}
- return str;
+ return p;
}
-StringRef parse_int(StringRef str, int fallback, int &dst, bool skip_space)
+const char *parse_int(const char *p, const char *end, int fallback, int &dst, bool skip_space)
{
if (skip_space) {
- str = drop_whitespace(str);
+ p = drop_whitespace(p, end);
}
- str = drop_plus(str);
- std::from_chars_result res = std::from_chars(str.begin(), str.end(), dst);
+ p = drop_plus(p, end);
+ std::from_chars_result res = std::from_chars(p, end, dst);
if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
dst = fallback;
}
- return StringRef(res.ptr, str.end());
+ return res.ptr;
}
} // namespace blender::io::obj