mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
5510089d45
* Rename simdjson_really_inline -> simdjson_inline I want to change the simdjson_really_inline macro to sometimes not force inlining. After that upcoming change, the name simdjson_really_inline will no longer makes sense. Rename simdjson_really_inline to simdjson_inline. This patch should not change semantics; simdjson_inline still forces inlining as before. Some functions still need to be really inlined for ABI reasons. (GCC's -Wpsabi complains otherwise.) Leave those functions marked as simdjson_really_inline. * Improve build times for debug builds simdjson_inline is used for most simdjson functions. It forces inlining. In unoptimized/debug builds, this can lead to a lot of machine code being generated (especially with Address Sanitizer), causing slow compilation. Change simdjson_inline to force inlining only for optimized builds. Sometimes, the programmer might want a slightly-optimized build and want fast compilation (e.g. GCC's -Og mode). Allow simdjson users to define the simdjson_inline macro themselves (e.g. on the command line: -Dsimdjson_inline=inline) in cases where the default behavior is undesired. This patch reduced build times by over 75% for ondemand_object_tests.cpp with GCC 9.4.0 and CMAKE_BUILD_TYPE=Debug on my AMD 5950X: Before: 6.885 6.683 6.971 6.957 6.949 seconds (5 samples) After: 1.492 1.551 1.494 1.490 1.531 seconds (5 samples)
66 lines
2.6 KiB
C++
66 lines
2.6 KiB
C++
namespace simdjson {
|
|
namespace SIMDJSON_IMPLEMENTATION {
|
|
namespace {
|
|
/// @private
|
|
namespace atomparsing {
|
|
|
|
// The string_to_uint32 is exclusively used to map literal strings to 32-bit values.
|
|
// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot
|
|
// be certain that the character pointer will be properly aligned.
|
|
// You might think that using memcpy makes this function expensive, but you'd be wrong.
|
|
// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false");
|
|
// to the compile-time constant 1936482662.
|
|
simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; }
|
|
|
|
|
|
// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive.
|
|
// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about.
|
|
simdjson_warn_unused
|
|
simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) {
|
|
uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++)
|
|
static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes");
|
|
std::memcpy(&srcval, src, sizeof(uint32_t));
|
|
return srcval ^ string_to_uint32(atom);
|
|
}
|
|
|
|
simdjson_warn_unused
|
|
simdjson_inline bool is_valid_true_atom(const uint8_t *src) {
|
|
return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0;
|
|
}
|
|
|
|
simdjson_warn_unused
|
|
simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) {
|
|
if (len > 4) { return is_valid_true_atom(src); }
|
|
else if (len == 4) { return !str4ncmp(src, "true"); }
|
|
else { return false; }
|
|
}
|
|
|
|
simdjson_warn_unused
|
|
simdjson_inline bool is_valid_false_atom(const uint8_t *src) {
|
|
return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0;
|
|
}
|
|
|
|
simdjson_warn_unused
|
|
simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) {
|
|
if (len > 5) { return is_valid_false_atom(src); }
|
|
else if (len == 5) { return !str4ncmp(src+1, "alse"); }
|
|
else { return false; }
|
|
}
|
|
|
|
simdjson_warn_unused
|
|
simdjson_inline bool is_valid_null_atom(const uint8_t *src) {
|
|
return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0;
|
|
}
|
|
|
|
simdjson_warn_unused
|
|
simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) {
|
|
if (len > 4) { return is_valid_null_atom(src); }
|
|
else if (len == 4) { return !str4ncmp(src, "null"); }
|
|
else { return false; }
|
|
}
|
|
|
|
} // namespace atomparsing
|
|
} // unnamed namespace
|
|
} // namespace SIMDJSON_IMPLEMENTATION
|
|
} // namespace simdjson
|