This massively improves the performance of tight loops relying on a type() call. (#721)
* This massively improves the performance of tight loops relying on a type() call. * Adding a few more benchmarks
This commit is contained in:
parent
326c175dcb
commit
befa6423be
|
@ -202,8 +202,8 @@ static void numbers_exceptions_size_scan(State& state) {
|
|||
std::vector<double> container;
|
||||
container.resize(arr.size());
|
||||
size_t pos = 0;
|
||||
for (double x : arr) {
|
||||
container[pos++] = x;
|
||||
for (auto e : arr) {
|
||||
container[pos++] = double(e);
|
||||
}
|
||||
if(pos != container.size()) { cerr << "bad count" << endl; }
|
||||
benchmark::DoNotOptimize(container.data());
|
||||
|
@ -213,6 +213,48 @@ static void numbers_exceptions_size_scan(State& state) {
|
|||
BENCHMARK(numbers_exceptions_size_scan);
|
||||
|
||||
|
||||
|
||||
static void numbers_type_exceptions_scan(State& state) {
|
||||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
dom::array arr = parser.load(NUMBERS_JSON);
|
||||
for (auto _ : state) {
|
||||
std::vector<double> container;
|
||||
for (auto e : arr) {
|
||||
dom::element_type actual_type = e.type();
|
||||
if(actual_type != dom::element_type::DOUBLE) {
|
||||
cerr << "found a node that is not an number?" << endl; break;
|
||||
}
|
||||
container.push_back(double(e));
|
||||
}
|
||||
benchmark::DoNotOptimize(container.data());
|
||||
benchmark::ClobberMemory();
|
||||
}
|
||||
}
|
||||
BENCHMARK(numbers_type_exceptions_scan);
|
||||
|
||||
static void numbers_type_exceptions_size_scan(State& state) {
|
||||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
dom::array arr = parser.load(NUMBERS_JSON);
|
||||
for (auto _ : state) {
|
||||
std::vector<double> container;
|
||||
container.resize(arr.size());
|
||||
size_t pos = 0;
|
||||
for (auto e : arr) {
|
||||
dom::element_type actual_type = e.type();
|
||||
if(actual_type != dom::element_type::DOUBLE) {
|
||||
cerr << "found a node that is not an number?" << endl; break;
|
||||
}
|
||||
container[pos++] = double(e);
|
||||
}
|
||||
if(pos != container.size()) { cerr << "bad count" << endl; }
|
||||
benchmark::DoNotOptimize(container.data());
|
||||
benchmark::ClobberMemory();
|
||||
}
|
||||
}
|
||||
BENCHMARK(numbers_type_exceptions_size_scan);
|
||||
|
||||
static void numbers_exceptions_load_scan(State& state) {
|
||||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
|
|
|
@ -44,7 +44,7 @@ constexpr const uint64_t JSON_VALUE_MASK = 0x00FFFFFFFFFFFFFF;
|
|||
constexpr const uint32_t JSON_COUNT_MASK = 0xFFFFFF;
|
||||
|
||||
/**
|
||||
* The possible types in the tape. Internal only.
|
||||
* The possible types in the tape.
|
||||
*/
|
||||
enum class tape_type {
|
||||
ROOT = 'r',
|
||||
|
@ -99,14 +99,14 @@ namespace simdjson::dom {
|
|||
* This is the type it is most easily cast to with get<>.
|
||||
*/
|
||||
enum class element_type {
|
||||
ARRAY, ///< dom::array
|
||||
OBJECT, ///< dom::object
|
||||
INT64, ///< int64_t
|
||||
UINT64, ///< uint64_t: any integer that fits in uint64_t but *not* int64_t
|
||||
DOUBLE, ///< double: Any number with a "." or "e" that fits in double.
|
||||
STRING, ///< std::string_view
|
||||
BOOL, ///< bool
|
||||
NULL_VALUE ///< null
|
||||
ARRAY = '[', ///< dom::array
|
||||
OBJECT = '{', ///< dom::object
|
||||
INT64 = 'l', ///< int64_t
|
||||
UINT64 = 'u', ///< uint64_t: any integer that fits in uint64_t but *not* int64_t
|
||||
DOUBLE = 'd', ///< double: Any number with a "." or "e" that fits in double.
|
||||
STRING = '"', ///< std::string_view
|
||||
BOOL = 't', ///< bool
|
||||
NULL_VALUE = 'n' ///< null
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -738,30 +738,8 @@ really_inline element::element(const document *_doc, size_t _json_index) noexcep
|
|||
|
||||
|
||||
inline element_type element::type() const noexcept {
|
||||
switch (tape_ref_type()) {
|
||||
case internal::tape_type::START_ARRAY:
|
||||
return element_type::ARRAY;
|
||||
case internal::tape_type::START_OBJECT:
|
||||
return element_type::OBJECT;
|
||||
case internal::tape_type::INT64:
|
||||
return element_type::INT64;
|
||||
case internal::tape_type::UINT64:
|
||||
return element_type::UINT64;
|
||||
case internal::tape_type::DOUBLE:
|
||||
return element_type::DOUBLE;
|
||||
case internal::tape_type::STRING:
|
||||
return element_type::STRING;
|
||||
case internal::tape_type::TRUE_VALUE:
|
||||
case internal::tape_type::FALSE_VALUE:
|
||||
return element_type::BOOL;
|
||||
case internal::tape_type::NULL_VALUE:
|
||||
return element_type::NULL_VALUE;
|
||||
case internal::tape_type::ROOT:
|
||||
case internal::tape_type::END_ARRAY:
|
||||
case internal::tape_type::END_OBJECT:
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
auto tape_type = tape_ref_type();
|
||||
return tape_type == internal::tape_type::FALSE_VALUE ? element_type::BOOL : static_cast<element_type>(tape_type);
|
||||
}
|
||||
really_inline bool element::is_null() const noexcept {
|
||||
return is_null_on_tape();
|
||||
|
|
Loading…
Reference in New Issue