Skip to content

Performance improvements #365

Closed
Closed
@TurpentineDistillery

Description

I propose some minor changes that yield substantial performance improvements.

diff --git a/src/json.hpp b/src/json.hpp
index a302bb0..0a8ab78 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8755,10 +8755,10 @@ basic_json_parser_66:
                 {
                     // copy unprocessed characters to line buffer
                     m_line_buffer.clear();
-                    for (m_cursor = m_start; m_cursor != m_limit; ++m_cursor)
-                    {
-                        m_line_buffer.append(1, static_cast<const char>(*m_cursor));
-                    }
+                    m_line_buffer.append(
+                            reinterpret_cast<const typename string_t::value_type*>(m_start),
+                            static_cast<size_t>(m_limit - m_start));
+                    m_cursor = m_limit;
                 }

                 // append n characters to make sure that there is sufficient
@@ -8770,11 +8770,13 @@ basic_json_parser_66:
             {
                 // delete processed characters from line buffer
                 m_line_buffer.erase(0, static_cast<size_t>(offset_start));
+
                 // read next line from input stream
-                std::string line;
-                std::getline(*m_stream, line, '\n');
+                m_line_buffer_tmp.clear();
+                std::getline(*m_stream, m_line_buffer_tmp, '\n');
                 // add line with newline symbol to the line buffer
-                m_line_buffer += line + "\n";
+                m_line_buffer += m_line_buffer_tmp;
+                m_line_buffer.push_back('\n');
             }

             // set pointers
@@ -8861,9 +8863,15 @@ basic_json_parser_66:
             // iterate the result between the quotes
             for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
             {
-                // process escaped characters
-                if (*i == '\\')
-                {
+                // number of non-escaped characters
+                const size_t n = static_cast<size_t>(std::find(i, m_cursor - 1, '\\') - i);
+
+                if(n != 0) {
+                    result.append(reinterpret_cast<const typename string_t::value_type*>(i), n);
+                    i += n-1; // -1 because will ++i
+                } else {
+                    // processing escaped character
+
                     // read next character
                     ++i;

@@ -8950,12 +8958,6 @@ basic_json_parser_66:
                         }
                     }
                 }
-                else
-                {
-                    // all other characters are just copied to the end of the
-                    // string
-                    result.append(1, static_cast<typename string_t::value_type>(*i));
-                }
             }

             return result;
@@ -9139,6 +9141,8 @@ basic_json_parser_66:
         std::istream* m_stream = nullptr;
         /// line buffer buffer for m_stream
         string_t m_line_buffer {};
+        /// used for filling m_line_buffer
+        string_t m_line_buffer_tmp {};
         /// the buffer pointer
         const lexer_char_t* m_content = nullptr;
         /// pointer to the beginning of the current symbol
Before
parse jeopardy.json                           1  1746079858 ns/op
parse canada.json                            50    49808100 ns/op
parse citm_catalog.json                      50    30050798 ns/op
parse twitter.json                          100    15523826 ns/op
parse numbers/floats.json                     5   539260495 ns/op
parse numbers/signed_ints.json                5   346619225 ns/op
parse numbers/unsigned_ints.json              5   348103862 ns/op
dump jeopardy.json                            1  1882424034 ns/op
dump jeopardy.json with indent                1  2333816314 ns/op

After:
parse jeopardy.json                           1  1392954141 ns/op
parse canada.json                            50    47828487 ns/op
parse citm_catalog.json                     100    19988139 ns/op
parse twitter.json                          100    10175643 ns/op
parse numbers/floats.json                     5   428099836 ns/op
parse numbers/signed_ints.json                5   232719693 ns/op
parse numbers/unsigned_ints.json              5   234741840 ns/op
dump jeopardy.json                            1  1871500322 ns/op
dump jeopardy.json with indent                1  2512231626 ns/op

Metadata

Assignees

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions