[Bf-blender-cvs] [aacb1f4756a] soc-2020-io-performance: Use stoi and stof instead of >> for faster parsing.
Ankit Meel
noreply at git.blender.org
Wed Jul 15 00:33:02 CEST 2020
Commit: aacb1f4756abcb725fa3b9729a4e669b4e52c410
Author: Ankit Meel
Date: Wed Jul 15 04:02:51 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rBaacb1f4756abcb725fa3b9729a4e669b4e52c410
Use stoi and stof instead of >> for faster parsing.
===================================================================
M source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
===================================================================
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
index 82a3831844d..bc708678559 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
@@ -34,32 +34,51 @@
namespace blender::io::obj {
+using std::string;
+
OBJImporter::OBJImporter(const OBJImportParams &import_params) : import_params_(import_params)
{
infile_.open(import_params_.filepath);
}
-static void split_by_char(std::string in_string, char delimiter, Vector<std::string> &r_out_list)
+static void split_by_char(string in_string, char delimiter, Vector<string> &r_out_list)
{
std::stringstream stream(in_string);
- std::string word{};
+ string word{};
while (std::getline(stream, word, delimiter)) {
+ if (word == "" || word[0] == ' ' || word[0] == '\0') {
+ continue;
+ }
r_out_list.append(word);
}
}
+static string first_word_of_string(string in_string)
+{
+ size_t pos = in_string.find_first_of(' ');
+ return pos == string::npos ? in_string.substr(0, 1) : in_string.substr(0, pos);
+}
+
+MALWAYS_INLINE void copy_string_to_float(float *dst, Span<string> src)
+{
+ dst[0] = std::stof(src[0]);
+ dst[1] = std::stof(src[1]);
+ if (src.size() == 3) {
+ dst[2] = std::stof(src[2]);
+ }
+}
+
void OBJImporter::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of_objects)
{
- std::string line;
+ string line;
/* Non owning raw pointer to the unique_ptr to a raw object.
* Needed to update object data in the same while loop.
* TODO ankitm Try to move the rest of the data parsing code in a conditional depending on a
* valid "o" object. */
std::unique_ptr<OBJRawObject> *curr_ob;
while (std::getline(infile_, line)) {
- std::stringstream s_line(line);
- std::string line_key;
- s_line >> line_key;
+ string line_key = first_word_of_string(line);
+ std::stringstream s_line(line.substr(line_key.size()));
if (line_key == "o") {
/* Update index offsets if an object has been processed already. */
@@ -73,7 +92,9 @@ void OBJImporter::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of
/* TODO ankitm Check that an object exists. */
else if (line_key == "v") {
MVert curr_vert;
- s_line >> curr_vert.co[0] >> curr_vert.co[1] >> curr_vert.co[2];
+ Vector<string> str_vert;
+ split_by_char(s_line.str(), ' ', str_vert);
+ copy_string_to_float(curr_vert.co, str_vert);
(*curr_ob)->vertices.append(curr_vert);
}
else if (line_key == "vn") {
@@ -81,20 +102,17 @@ void OBJImporter::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of
}
else if (line_key == "vt") {
MLoopUV curr_tex_vert;
- s_line >> curr_tex_vert.uv[0] >> curr_tex_vert.uv[1];
+ Vector<string> str_vert;
+ split_by_char(s_line.str(), ' ', str_vert);
+ copy_string_to_float(curr_tex_vert.uv, str_vert);
(*curr_ob)->texture_vertices.append(curr_tex_vert);
}
else if (line_key == "f") {
OBJFaceElem curr_face;
- std::string str_corners_line = s_line.str();
- Vector<std::string> str_corners_split;
+ string str_corners_line = s_line.str();
+ Vector<string> str_corners_split;
split_by_char(str_corners_line, ' ', str_corners_split);
for (auto str_corner : str_corners_split) {
- if (str_corner == "f") {
- /* Hack, since that's how streams change to strings. Ideally the line_key should be a
- * string and then a stream is made from the rest of the line. */
- continue;
- }
OBJFaceCorner corner;
size_t n_slash = std::count(str_corner.begin(), str_corner.end(), '/');
if (n_slash == 0) {
@@ -104,7 +122,7 @@ void OBJImporter::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of
Vector<std::string> vert_texture;
split_by_char(str_corner, '/', vert_texture);
corner.vert_index = std::stoi(vert_texture[0]);
- corner.tex_vert_index = vert_texture[1].empty() ? -1 : std::stoi(vert_texture[1]);
+ corner.tex_vert_index = vert_texture.size() >= 1 ? -1 : std::stoi(vert_texture[1]);
}
else if (n_slash == 2) {
Vector<std::string> vert_normal;
More information about the Bf-blender-cvs
mailing list