Skip to content

Commit 90aad0d

Browse files
authored
Optimise the JSON parser (#2241)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 47b312f commit 90aad0d

File tree

7 files changed

+514
-486
lines changed

7 files changed

+514
-486
lines changed

src/core/json/include/sourcemeta/core/json_object.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ template <typename Key, typename Value, typename Hash> class JSONObject {
183183
/// Check if the object is empty
184184
[[nodiscard]] inline auto empty() const -> bool { return this->data.empty(); }
185185

186+
/// Reserve capacity for a given number of entries
187+
inline auto reserve(const size_type capacity) -> void {
188+
this->data.reserve(capacity);
189+
}
190+
186191
/// Access an object entry by its underlying positional index
187192
[[nodiscard]] inline auto at(const size_type index) const -> const Entry & {
188193
return this->data.at(index);

src/core/json/json.cc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <fstream> // std::ifstream
1414
#include <istream> // std::basic_istream
1515
#include <ostream> // std::basic_ostream
16+
#include <sstream> // std::basic_ostringstream
1617
#include <system_error> // std::make_error_code, std::errc
1718

1819
namespace sourcemeta::core {
@@ -21,7 +22,20 @@ namespace sourcemeta::core {
2122
auto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,
2223
std::uint64_t &line, std::uint64_t &column,
2324
const JSON::ParseCallback &callback) -> JSON {
24-
return internal_parse_json(stream, line, column, callback);
25+
const auto start_position{stream.tellg()};
26+
std::basic_ostringstream<JSON::Char, JSON::CharTraits> buffer;
27+
buffer << stream.rdbuf();
28+
const auto input{buffer.str()};
29+
const char *cursor{input.data()};
30+
const char *end{input.data() + input.size()};
31+
auto result{internal_parse_json(cursor, end, line, column, callback)};
32+
if (start_position != static_cast<std::streampos>(-1)) {
33+
const auto consumed{static_cast<std::streamoff>(cursor - input.data())};
34+
stream.clear();
35+
stream.seekg(start_position + consumed);
36+
}
37+
38+
return result;
2539
}
2640

2741
auto parse_json(const std::basic_string<JSON::Char, JSON::CharTraits> &input,

0 commit comments

Comments
 (0)