mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d1de135ebd | |||
| 0edf1008c9 | |||
| 6a0d7bcb55 | |||
| 6f196d0af0 | |||
| c3414a1234 | |||
| 5d2107b470 | |||
| 90aa198430 | |||
| 02b488b88d | |||
| 47e3e95867 | |||
| 588c0677f5 |
@@ -31,7 +31,7 @@ A clear and concise description of any alternative solutions or features you've
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
||||
**Are you willing to contribute code or documentation toward this new feature?**
|
||||
** Are you willing to contribute code or documentation toward this new feature? **
|
||||
If you plan to contribute to simdjson, please read our
|
||||
* CONTRIBUTING guide: https://github.com/simdjson/simdjson/blob/master/CONTRIBUTING.md and our
|
||||
* HACKING guide: https://github.com/simdjson/simdjson/blob/master/HACKING.md
|
||||
|
||||
@@ -31,14 +31,3 @@ jobs:
|
||||
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json &&
|
||||
cd ../tests/installation_tests/find &&
|
||||
mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH=../../../build/destination .. && cmake --build .
|
||||
- name: Use cmake (shared)
|
||||
run: |
|
||||
mkdir buildshared &&
|
||||
cd buildshared &&
|
||||
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
|
||||
cmake --build . &&
|
||||
ctest --output-on-failure -LE explicitonly -j &&
|
||||
cmake --install . &&
|
||||
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json &&
|
||||
cd ../tests/installation_tests/find &&
|
||||
mkdir buildshared && cd buildshared && cmake -DCMAKE_INSTALL_PREFIX:PATH=../../../buildshared/destination .. && cmake --build .
|
||||
|
||||
@@ -32,6 +32,7 @@ jobs:
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
|
||||
ctest --output-on-failure -LE explicitonly -j
|
||||
- name: Use cmake with undefined sanitizer
|
||||
run: |
|
||||
mkdir builddebugundefsani &&
|
||||
|
||||
Vendored
+3
-2
@@ -3,7 +3,7 @@
|
||||
{"column": 95 },
|
||||
{"column": 120 }
|
||||
],
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"files.trimTrailingWhitespace": false,
|
||||
"files.associations": {
|
||||
".clangd": "yaml",
|
||||
"array": "cpp",
|
||||
@@ -99,5 +99,6 @@
|
||||
"shared_mutex": "cpp",
|
||||
"ranges": "cpp",
|
||||
"span": "cpp"
|
||||
}
|
||||
},
|
||||
"editor.trimAutoWhitespace": true
|
||||
}
|
||||
+5
-32
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
|
||||
project(
|
||||
simdjson
|
||||
# The version number is modified by tools/release.py
|
||||
VERSION 3.6.0
|
||||
VERSION 3.2.3
|
||||
DESCRIPTION "Parsing gigabytes of JSON per second"
|
||||
HOMEPAGE_URL "https://simdjson.org/"
|
||||
LANGUAGES CXX C
|
||||
@@ -20,10 +20,8 @@ string(
|
||||
# ---- Options, variables ----
|
||||
|
||||
# These version numbers are modified by tools/release.py
|
||||
set(SIMDJSON_LIB_VERSION "19.0.0" CACHE STRING "simdjson library version")
|
||||
set(SIMDJSON_LIB_SOVERSION "19" CACHE STRING "simdjson library soversion")
|
||||
|
||||
option(SIMDJSON_BUILD_STATIC_LIB "Build simdjson_static library along with simdjson" OFF)
|
||||
set(SIMDJSON_LIB_VERSION "16.0.0" CACHE STRING "simdjson library version")
|
||||
set(SIMDJSON_LIB_SOVERSION "16" CACHE STRING "simdjson library soversion")
|
||||
|
||||
option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON)
|
||||
|
||||
@@ -58,17 +56,8 @@ include(cmake/developer-options.cmake)
|
||||
|
||||
# ---- simdjson library ----
|
||||
|
||||
set(SIMDJSON_SOURCES src/simdjson.cpp)
|
||||
|
||||
add_library(simdjson ${SIMDJSON_SOURCES})
|
||||
add_library(simdjson src/simdjson.cpp)
|
||||
add_library(simdjson::simdjson ALIAS simdjson)
|
||||
set(SIMDJSON_LIBRARIES simdjson)
|
||||
|
||||
if(SIMDJSON_BUILD_STATIC_LIB)
|
||||
add_library(simdjson_static STATIC ${SIMDJSON_SOURCES})
|
||||
add_library(simdjson::simdjson_static ALIAS simdjson_static)
|
||||
list(APPEND SIMDJSON_LIBRARIES simdjson_static)
|
||||
endif()
|
||||
|
||||
set_target_properties(
|
||||
simdjson PROPERTIES
|
||||
@@ -128,9 +117,6 @@ if(SIMDJSON_ENABLE_THREADS)
|
||||
endif()
|
||||
|
||||
simdjson_apply_props(simdjson)
|
||||
if(SIMDJSON_BUILD_STATIC_LIB)
|
||||
simdjson_apply_props(simdjson_static)
|
||||
endif()
|
||||
|
||||
# ---- Install rules ----
|
||||
|
||||
@@ -152,6 +138,7 @@ install(
|
||||
ARCHIVE COMPONENT simdjson_Development
|
||||
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
|
||||
configure_file(cmake/simdjson-config.cmake.in simdjson-config.cmake @ONLY)
|
||||
|
||||
write_basic_package_version_file(
|
||||
@@ -180,20 +167,6 @@ install(
|
||||
COMPONENT simdjson_Development
|
||||
)
|
||||
|
||||
if(SIMDJSON_BUILD_STATIC_LIB)
|
||||
install(
|
||||
TARGETS simdjson_static
|
||||
EXPORT simdjson_staticTargets
|
||||
ARCHIVE COMPONENT simdjson_Development
|
||||
)
|
||||
install(
|
||||
EXPORT simdjson_staticTargets
|
||||
NAMESPACE simdjson::
|
||||
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
|
||||
COMPONENT simdjson_Development
|
||||
)
|
||||
endif()
|
||||
|
||||
# pkg-config
|
||||
include(cmake/JoinPaths.cmake)
|
||||
join_paths(PKGCONFIG_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "3.6.0"
|
||||
PROJECT_NUMBER = "3.2.3"
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
@@ -114,6 +114,7 @@ set(SIMDJSON_CXX_STANDARD 17 CACHE STRING "the C++ standard to use for simdjson"
|
||||
set(CMAKE_CXX_STANDARD ${SIMDJSON_CXX_STANDARD})
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_MACOSX_RPATH OFF)
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD ON)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
set(SIMDJSON_STRUCTURAL_INDEXER_STEP CACHE STRING "the SIMDJSON_STRUCTURAL_INDEXER_STEP variable")
|
||||
|
||||
@@ -4,4 +4,3 @@ if("@SIMDJSON_ENABLE_THREADS@")
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/simdjsonTargets.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/simdjson_staticTargets.cmake" OPTIONAL)
|
||||
|
||||
+7
-163
@@ -30,7 +30,6 @@ An overview of what you need to know to use simdjson, with examples.
|
||||
- [Dynamic Number Types](#dynamic-number-types)
|
||||
- [Raw Strings](#raw-strings)
|
||||
- [General Direct Access to the Raw JSON String](#general-direct-access-to-the-raw-json-string)
|
||||
- [Storing Directly into an Existing String Instance](#storing-directly-into-an-existing-string-instance)
|
||||
- [Thread Safety](#thread-safety)
|
||||
- [Standard Compliance](#standard-compliance)
|
||||
- [Backwards Compatibility](#backwards-compatibility)
|
||||
@@ -180,8 +179,8 @@ strcpy(json, "[1]");
|
||||
ondemand::document doc = parser.iterate(json, strlen(json), sizeof(json));
|
||||
```
|
||||
|
||||
The simdjson library will also accept `std::string` instances. If the provided
|
||||
reference is non-const, it will allocate padding as needed.
|
||||
The simdjson library will also accept `std::string` instances, as long as the `capacity()` of
|
||||
the string exceeds the `size()` by at least `SIMDJSON_PADDING`. You can increase the `capacity()` with the `reserve()` function of your strings.
|
||||
|
||||
You can copy your data directly on a `simdjson::padded_string` as follows:
|
||||
|
||||
@@ -371,11 +370,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
||||
> as a key, it will not be recognized. This is not generally a problem. Nevertheless, if you do need
|
||||
> to support escaped keys, the method `unescaped_key()` provides the desired unescaped keys by
|
||||
> parsing and writing out the unescaped keys to a string buffer and returning a `std::string_view`
|
||||
> instance. The `unescaped_key` takes an optional Boolean value: passing it true will decode invalid
|
||||
> Unicode sequences with replacement, meaning that the decoding always succeeds but bogus Unicode
|
||||
> replacement characters are inserted. In general, you should expect a performance penalty
|
||||
> when using `unescaped_key()` compared to `key()` because of the string processing: the `key()`
|
||||
> function just points inside the source JSON document.
|
||||
> instance. You should expect a performance penalty when using `unescaped_key()`.
|
||||
>
|
||||
> ```c++
|
||||
> auto json = R"({"k\u0065y": 1})"_padded;
|
||||
@@ -419,10 +414,8 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
||||
step through each value in the JSON array.
|
||||
|
||||
If you know the type of the value, you can cast it right there, too! `for (double value : array) { ... }`.
|
||||
|
||||
You may also use explicit iterators: `for(auto i = array.begin(); i != array.end(); i++) {}`. You can check that an array is empty with the condition `auto i = array.begin(); if(i == array.end()) {...}`.
|
||||
* **Object Iteration:** You can iterate through an object's fields, as well: `for (auto field : object) { ... }`. You may also use explicit iterators : `for(auto i = object.begin(); i != object.end(); i++) { auto field = *i; .... }`. You can check that an object is empty with the condition `auto i = object.begin(); if(i == object.end()) {...}`.
|
||||
- `field.unescaped_key()` will get you the unescaped key string. E.g., the JSON string `"\u00e1"` becomes the Unicode string `á`. Optionally, you pass `true` as a parameter to the `unescaped_key` method if you want invalid escape sequences to be replaced by a default replacement character (e.g., `\ud800\ud801\ud811`): otherwise bad escape sequences lead to an immediate error.
|
||||
* **Object Iteration:** You can iterate through an object's fields, as well: `for (auto field : object) { ... }`
|
||||
- `field.unescaped_key()` will get you the unescaped key string.
|
||||
- `field.value()` will get you the value, which you can then use all these other methods on.
|
||||
* **Array Index:** Because it is forward-only, you cannot look up an array element by index by index. Instead,
|
||||
you should iterate through the array and keep an index yourself.
|
||||
@@ -1654,7 +1647,7 @@ JSON string to a user-provided buffer:
|
||||
|
||||
General Direct Access to the Raw JSON String
|
||||
--------------------------------
|
||||
If your value is a string, the `raw_json_string` you with `get_raw_json_string()` gives you direct access to the unprocessed
|
||||
If your value is a string, the `raw_json_string` gives you direct access to the unprocess
|
||||
string. The simdjson library allows you to have access to the raw underlying JSON
|
||||
more generally.
|
||||
|
||||
@@ -1723,82 +1716,6 @@ obj.reset(); // revise the object
|
||||
uint64_t x = obj["value"]; // gives me 123
|
||||
```
|
||||
|
||||
You can use `raw_json()` with the values inside an array and object. When
|
||||
calling `raw_json()` on an untyped value, it acts as `raw_json()` when the
|
||||
value is an array or an object. Otherwise, it acts as `raw_json_token()`.
|
||||
It is useful if you do not care for the type of the value and just wants a
|
||||
string representation.
|
||||
|
||||
```C++
|
||||
auto json = R"( [1,2,"fds", {"a":1}, [1,344]] )"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc = parser.iterate(json);
|
||||
size_t counter = 0;
|
||||
for(auto array: doc) {
|
||||
std::string_view raw = array.raw_json();
|
||||
// will capture "1", "2", "\"fds\"", "{\"a\":1}", "[1,344]"
|
||||
}
|
||||
```
|
||||
|
||||
```C++
|
||||
auto json = R"( {"key1":1,"key2":2,"key3":"fds", "key4":{"a":1}, "key5":[1,344]} )"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc = parser.iterate(json);
|
||||
size_t counter = 0;
|
||||
for(auto key_value: doc.get_object()) {
|
||||
std::string_view raw = key_value.value().raw_json();
|
||||
// will capture "1", "2", "\"fds\"", "{\"a\":1}", "[1,344]"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Storing Directly into an Existing String Instance
|
||||
-----------------------------------------------------
|
||||
|
||||
The simdjson library favours the use of `std::string_view` instances because
|
||||
it tends to lead to better performance due to causing fewer memory allocations.
|
||||
However, they are cases where you need to store a string result in an `std::string``
|
||||
instance. You can do so with a templated version of the `to_string()` method which takes as
|
||||
a parameter a reference to an `std::string`.
|
||||
|
||||
```C++
|
||||
auto json = R"({
|
||||
"name": "Daniel",
|
||||
"age": 42
|
||||
})"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc = parser.iterate(json);
|
||||
std::string name;
|
||||
doc["name"].get_string(name);
|
||||
```
|
||||
|
||||
The same routine can be written without exceptions handling:
|
||||
|
||||
```C++
|
||||
std::string name;
|
||||
auto err = doc["name"].get_string(name);
|
||||
if(err) { /* handle error */ }
|
||||
```
|
||||
|
||||
The `std::string` instance, once created, is independent. Unlike our `std::string_view` instances,
|
||||
it does not point at data that is within our `parser` instance. The same caveat applies: you should
|
||||
only consume a JSON string once.
|
||||
|
||||
Because `get_string()` is a template that requires a type that can be assigned an `std::string`, you
|
||||
can use it with features such as `std::optional`:
|
||||
|
||||
```C++
|
||||
auto json = R"({ "foo1": "3.1416" } )"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc = parser.iterate(json);
|
||||
std::optional<std::string> value;
|
||||
if(doc["foo1"].get_string(value)) { /* error */ }
|
||||
// value was populated with "3.1416"
|
||||
```
|
||||
|
||||
You should be mindful of the trade-off: allocating multiple
|
||||
`std::string` instances can become expensive.
|
||||
|
||||
Thread Safety
|
||||
-------------
|
||||
|
||||
@@ -2027,79 +1944,6 @@ bool example() {
|
||||
}
|
||||
```
|
||||
|
||||
* Example 3: CRT
|
||||
|
||||
```C++
|
||||
|
||||
bool example() {
|
||||
padded_string padded_input_json = R"([
|
||||
{ "monitor": [
|
||||
{ "id": "monitor", "type": "toggle", "label": "monitor" },
|
||||
{ "id": "profile", "type": "selector", "label": "collection" },
|
||||
{ "id": "overlay", "type": "selector", "label": "overlay" },
|
||||
{ "id": "zoom", "type": "toggleSlider", "label": "zoom" }
|
||||
] },
|
||||
|
||||
{ "crt": [
|
||||
{ "id": "system", "type": "multi", "label": "system", "choices": "PAL, NTSC" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "brightness", "type": "slider", "icon": "brightness" },
|
||||
{ "id": "contrast", "type": "slider", "icon": "contrast" },
|
||||
{ "id": "saturation", "type": "slider", "icon": "saturation" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "overscan", "type": "toggleSlider", "label": "overscan" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "emulation", "type": "toggle", "label": "CRT emulation" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "curve", "type": "toggleSlider", "label": "curve" },
|
||||
{ "id": "bleed", "type": "toggleSlider", "label": "bleed" },
|
||||
{ "id": "vignette", "type": "toggleSlider", "label": "vignette" },
|
||||
{ "id": "scanlines", "type": "toggleSlider", "label": "scanlines" },
|
||||
{ "id": "gridlines", "type": "toggleSlider", "label": "gridlines" },
|
||||
{ "id": "glow", "type": "toggleSlider", "label": "glow" },
|
||||
{ "id": "flicker", "type": "toggleSlider", "label": "flicker" },
|
||||
{ "id": "noise", "type": "toggleSlider", "label": "noise" },
|
||||
{}
|
||||
] }
|
||||
])"_padded;
|
||||
auto parser = ondemand::parser{};
|
||||
auto doc = parser.iterate(padded_input_json);
|
||||
auto root_array = doc.get_array();
|
||||
// the root should be an object, not an array, but that's the JSON we are
|
||||
// given.
|
||||
for (ondemand::object node : root_array) {
|
||||
// We know that we are going to have just one element in the object.
|
||||
for (auto field : node) {
|
||||
std::cout << "\n\ntop level:" << field.key() << std::endl;
|
||||
// You can get a proper std::string_view for the key with:
|
||||
// std::string_view key = field.unescaped_key();
|
||||
// and second for-range loop to get child-elements here
|
||||
for (ondemand::object inner_object : field.value()) {
|
||||
auto i = inner_object.begin();
|
||||
if (i == inner_object.end()) {
|
||||
std::cout << "empty object" << std::endl;
|
||||
continue;
|
||||
} else {
|
||||
for (; i != inner_object.end(); ++i) {
|
||||
auto inner_field = *i;
|
||||
std::cout << '"' << inner_field.key()
|
||||
<< "\" : " << inner_field.value() << ", ";
|
||||
// You can get proper std::string_view for the key and value with:
|
||||
// std::string_view inner_key = field.unescaped_key();
|
||||
// std::string_view value_str = field.value();
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
// You can break here if you only want just the first element.
|
||||
// break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
Performance Tips
|
||||
--------
|
||||
@@ -2125,4 +1969,4 @@ Performance Tips
|
||||
std::string_view year = data["year"];
|
||||
std::string_view rating = data["rating"];
|
||||
```
|
||||
- To better understand the operation of your On Demand parser, and whether it is performing as well as you think it should be, there is a logger feature built in to simdjson! To use it, define the pre-processor directive `SIMDJSON_VERBOSE_LOGGING` prior to including the `simdjson.h` header, which enables logging in simdjson. Run your code. It may generate a lot of logging output; adding printouts from your application that show each section may be helpful. The log's output will show step-by-step information on state, buffer pointer position, depth, and key retrieval status. Importantly, unless `SIMDJSON_VERBOSE_LOGGING` is defined, logging is entirely disabled and thus carries no overhead.
|
||||
- To better understand the operation of your On Demand parser, and whether it is performing as well as you think it should be, there is a logger feature built in to simdjson! To use it, define the pre-processor directive `SIMDJSON_VERBOSE_LOGGING` prior to including the `simdjson.h` header, which enables logging in simdjson. Run your code. It may generate a lot of logging output; adding printouts from your application that show each section may be helpful. The log's output will show step-by-step information on state, buffer pointer position, depth, and key retrieval status. Importantly, unless `SIMDJSON_VERBOSE_LOGGING` is defined, logging is entirely disabled and thus carries no overhead.
|
||||
@@ -0,0 +1,277 @@
|
||||
number of iterations 3000
|
||||
|
||||
| Original (jsonexamples/twitter-padded-numbers.json) 773
|
||||
|- 18-digit numbers (jsonexamples/twitter18.json) 757
|
||||
|- 8-digit numbers (jsonexamples/twitter8.json) 766
|
||||
|- 1-digit numbers (jsonexamples/twitter1.json) 544
|
||||
| |- strings -> no backslashes (jsonexamples/twitter1-nobackslash.json) 499
|
||||
| |- strings -> no utf8 (jsonexamples/twitter1-nobackslash-noutf8.json) 489
|
||||
| |- strings -> empty strings (jsonexamples/twitter1-emptystring.json) 351
|
||||
| |- no number/bool/null -> all strings (jsonexamples/twitter-allstrings.json) 216
|
||||
| |- no objects -> all arrays (jsonexamples/twitter-allstrings-arrays.json) 427
|
||||
| |- arrays -> no nested arrays (jsonexamples/twitter-allstrings-flatarray.json) 3
|
||||
|
||||
jsonexamples/twitter-padded-numbers.json
|
||||
========================================
|
||||
10306 blocks - 659626 bytes - 55262 structurals ( 8.4 %)
|
||||
special blocks with: utf8 2289 ( 22.2 %) - escape 604 ( 5.9 %) - 0 structurals 1270 ( 12.3 %) - 1+ structurals 9037 ( 87.7 %) - 8+ structurals 2576 ( 25.0 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 1096 ( 10.6 %) - escape 646 ( 6.3 %) - 0 structurals 932 ( 9.0 %) - 1+ structurals 932 ( 9.0 %) - 8+ structurals 2843 ( 27.6 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 20.7212 ns per block ( 97.66%) - 0.3238 ns per byte - 3.8647 ns per structural - 3.0885 GB/s
|
||||
| Cycles : 64.1524 per block ( 97.86%) - 1.0024 per byte - 11.9652 per structural - 3.096 GHz est. frequency
|
||||
| Instructions : 200.2565 per block (100.00%) - 3.1291 per byte - 37.3502 per structural - 3.122 per cycle
|
||||
| Misses : 873 branch misses ( 93.08%) - 0 cache misses ( 0.00%) - 28032.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 6.0073 ns per block ( 28.31%) - 0.0939 ns per byte - 1.1204 ns per structural - 10.6534 GB/s
|
||||
| Cycles : 18.6130 per block ( 28.39%) - 0.2908 per byte - 3.4715 per structural - 3.098 GHz est. frequency
|
||||
| Instructions : 61.8107 per block ( 30.87%) - 0.9658 per byte - 11.5284 per structural - 3.321 per cycle
|
||||
| Misses : 93 branch misses ( 9.92%) - 0 cache misses ( 0.00%) - 12229.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 14.6555 ns per block ( 69.07%) - 0.2290 ns per byte - 2.7334 ns per structural - 4.3668 GB/s
|
||||
| Cycles : 45.3587 per block ( 69.19%) - 0.7088 per byte - 8.4599 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 138.4458 per block ( 69.13%) - 2.1633 per byte - 25.8217 per structural - 3.052 per cycle
|
||||
| Misses : 773 branch misses ( 82.42%) - 0 cache misses ( 0.00%) - 15925.00 cache references
|
||||
|
||||
4682.2 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter18.json
|
||||
===========================
|
||||
10306 blocks - 659626 bytes - 55262 structurals ( 8.4 %)
|
||||
special blocks with: utf8 2289 ( 22.2 %) - escape 604 ( 5.9 %) - 0 structurals 1270 ( 12.3 %) - 1+ structurals 9037 ( 87.7 %) - 8+ structurals 2585 ( 25.1 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 1096 ( 10.6 %) - escape 646 ( 6.3 %) - 0 structurals 932 ( 9.0 %) - 1+ structurals 932 ( 9.0 %) - 8+ structurals 2847 ( 27.6 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 21.1739 ns per block ( 93.63%) - 0.3309 ns per byte - 3.9492 ns per structural - 3.0225 GB/s
|
||||
| Cycles : 65.5570 per block ( 97.40%) - 1.0244 per byte - 12.2271 per structural - 3.096 GHz est. frequency
|
||||
| Instructions : 205.6160 per block (100.00%) - 3.2129 per byte - 38.3498 per structural - 3.136 per cycle
|
||||
| Misses : 856 branch misses ( 97.20%) - 0 cache misses ( 0.00%) - 28297.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 5.9968 ns per block ( 26.52%) - 0.0937 ns per byte - 1.1185 ns per structural - 10.6720 GB/s
|
||||
| Cycles : 18.5808 per block ( 27.61%) - 0.2903 per byte - 3.4655 per structural - 3.098 GHz est. frequency
|
||||
| Instructions : 61.8107 per block ( 30.06%) - 0.9658 per byte - 11.5284 per structural - 3.327 per cycle
|
||||
| Misses : 103 branch misses ( 11.70%) - 0 cache misses ( 0.00%) - 12271.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 15.0964 ns per block ( 66.75%) - 0.2359 ns per byte - 2.8157 ns per structural - 4.2393 GB/s
|
||||
| Cycles : 46.7271 per block ( 69.43%) - 0.7301 per byte - 8.7151 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 143.8053 per block ( 69.94%) - 2.2470 per byte - 26.8213 per structural - 3.078 per cycle
|
||||
| Misses : 757 branch misses ( 85.96%) - 0 cache misses ( 0.00%) - 16107.00 cache references
|
||||
|
||||
4582.1 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter8.json
|
||||
==========================
|
||||
10306 blocks - 659626 bytes - 55262 structurals ( 8.4 %)
|
||||
special blocks with: utf8 2289 ( 22.2 %) - escape 604 ( 5.9 %) - 0 structurals 1270 ( 12.3 %) - 1+ structurals 9037 ( 87.7 %) - 8+ structurals 2576 ( 25.0 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 1096 ( 10.6 %) - escape 646 ( 6.3 %) - 0 structurals 932 ( 9.0 %) - 1+ structurals 932 ( 9.0 %) - 8+ structurals 2843 ( 27.6 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 20.6976 ns per block ( 97.48%) - 0.3234 ns per byte - 3.8603 ns per structural - 3.0920 GB/s
|
||||
| Cycles : 64.0733 per block ( 97.72%) - 1.0012 per byte - 11.9504 per structural - 3.096 GHz est. frequency
|
||||
| Instructions : 200.2565 per block (100.00%) - 3.1291 per byte - 37.3502 per structural - 3.125 per cycle
|
||||
| Misses : 860 branch misses ( 91.48%) - 0 cache misses ( 0.00%) - 28700.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 6.0103 ns per block ( 28.31%) - 0.0939 ns per byte - 1.1210 ns per structural - 10.6481 GB/s
|
||||
| Cycles : 18.6231 per block ( 28.40%) - 0.2910 per byte - 3.4734 per structural - 3.099 GHz est. frequency
|
||||
| Instructions : 61.8107 per block ( 30.87%) - 0.9658 per byte - 11.5284 per structural - 3.319 per cycle
|
||||
| Misses : 102 branch misses ( 10.85%) - 0 cache misses ( 0.00%) - 11933.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 14.6407 ns per block ( 68.95%) - 0.2288 ns per byte - 2.7307 ns per structural - 4.3712 GB/s
|
||||
| Cycles : 45.3059 per block ( 69.10%) - 0.7079 per byte - 8.4501 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 138.4458 per block ( 69.13%) - 2.1633 per byte - 25.8217 per structural - 3.056 per cycle
|
||||
| Misses : 766 branch misses ( 81.48%) - 0 cache misses ( 0.00%) - 16566.00 cache references
|
||||
|
||||
4687.6 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter1.json
|
||||
==========================
|
||||
10306 blocks - 659626 bytes - 55262 structurals ( 8.4 %)
|
||||
special blocks with: utf8 2289 ( 22.2 %) - escape 604 ( 5.9 %) - 0 structurals 1270 ( 12.3 %) - 1+ structurals 9037 ( 87.7 %) - 8+ structurals 2584 ( 25.1 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 1096 ( 10.6 %) - escape 646 ( 6.3 %) - 0 structurals 932 ( 9.0 %) - 1+ structurals 932 ( 9.0 %) - 8+ structurals 2859 ( 27.7 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 20.1200 ns per block ( 93.76%) - 0.3144 ns per byte - 3.7526 ns per structural - 3.1808 GB/s
|
||||
| Cycles : 62.2865 per block ( 97.52%) - 0.9733 per byte - 11.6172 per structural - 3.096 GHz est. frequency
|
||||
| Instructions : 194.5666 per block (100.00%) - 3.0402 per byte - 36.2889 per structural - 3.124 per cycle
|
||||
| Misses : 673 branch misses ( 97.88%) - 0 cache misses ( 0.00%) - 28320.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 6.0046 ns per block ( 27.98%) - 0.0938 ns per byte - 1.1199 ns per structural - 10.6582 GB/s
|
||||
| Cycles : 18.6140 per block ( 29.14%) - 0.2909 per byte - 3.4717 per structural - 3.100 GHz est. frequency
|
||||
| Instructions : 61.8107 per block ( 31.77%) - 0.9658 per byte - 11.5284 per structural - 3.321 per cycle
|
||||
| Misses : 113 branch misses ( 16.43%) - 0 cache misses ( 0.00%) - 12175.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 14.0716 ns per block ( 65.57%) - 0.2199 ns per byte - 2.6245 ns per structural - 4.5480 GB/s
|
||||
| Cycles : 43.5464 per block ( 68.18%) - 0.6804 per byte - 8.1219 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 132.7559 per block ( 68.23%) - 2.0744 per byte - 24.7605 per structural - 3.049 per cycle
|
||||
| Misses : 544 branch misses ( 79.11%) - 0 cache misses ( 0.00%) - 16212.00 cache references
|
||||
|
||||
4822.1 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter1-nobackslash.json
|
||||
======================================
|
||||
10306 blocks - 659626 bytes - 55262 structurals ( 8.4 %)
|
||||
special blocks with: utf8 2289 ( 22.2 %) - escape 0 ( 0.0 %) - 0 structurals 1270 ( 12.3 %) - 1+ structurals 9037 ( 87.7 %) - 8+ structurals 2584 ( 25.1 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 1096 ( 10.6 %) - escape 0 ( 0.0 %) - 0 structurals 932 ( 9.0 %) - 1+ structurals 932 ( 9.0 %) - 8+ structurals 2859 ( 27.7 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 19.3473 ns per block ( 94.75%) - 0.3023 ns per byte - 3.6085 ns per structural - 3.3078 GB/s
|
||||
| Cycles : 59.8930 per block ( 97.21%) - 0.9359 per byte - 11.1707 per structural - 3.096 GHz est. frequency
|
||||
| Instructions : 191.2882 per block (100.00%) - 2.9890 per byte - 35.6774 per structural - 3.194 per cycle
|
||||
| Misses : 624 branch misses ( 99.02%) - 2 cache misses ( 30.96%) - 28632.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 5.9519 ns per block ( 29.15%) - 0.0930 ns per byte - 1.1101 ns per structural - 10.7526 GB/s
|
||||
| Cycles : 18.4460 per block ( 29.94%) - 0.2882 per byte - 3.4404 per structural - 3.099 GHz est. frequency
|
||||
| Instructions : 61.1661 per block ( 31.98%) - 0.9558 per byte - 11.4082 per structural - 3.316 per cycle
|
||||
| Misses : 92 branch misses ( 14.60%) - 1 cache misses ( 15.48%) - 12277.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 13.3283 ns per block ( 65.28%) - 0.2083 ns per byte - 2.4859 ns per structural - 4.8016 GB/s
|
||||
| Cycles : 41.2453 per block ( 66.95%) - 0.6445 per byte - 7.6927 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 130.1221 per block ( 68.02%) - 2.0332 per byte - 24.2693 per structural - 3.155 per cycle
|
||||
| Misses : 499 branch misses ( 79.19%) - 1 cache misses ( 15.48%) - 16358.00 cache references
|
||||
|
||||
5014.7 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter1-nobackslash-noutf8.json
|
||||
=============================================
|
||||
10306 blocks - 659626 bytes - 55262 structurals ( 8.4 %)
|
||||
special blocks with: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 1270 ( 12.3 %) - 1+ structurals 9037 ( 87.7 %) - 8+ structurals 2584 ( 25.1 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 932 ( 9.0 %) - 1+ structurals 932 ( 9.0 %) - 8+ structurals 2859 ( 27.7 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 18.9506 ns per block ( 97.78%) - 0.2961 ns per byte - 3.5345 ns per structural - 3.3771 GB/s
|
||||
| Cycles : 58.6756 per block ( 97.97%) - 0.9168 per byte - 10.9437 per structural - 3.096 GHz est. frequency
|
||||
| Instructions : 186.6244 per block (100.00%) - 2.9161 per byte - 34.8076 per structural - 3.181 per cycle
|
||||
| Misses : 634 branch misses ( 99.08%) - 0 cache misses ( 0.00%) - 28596.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 5.4613 ns per block ( 28.18%) - 0.0853 ns per byte - 1.0186 ns per structural - 11.7184 GB/s
|
||||
| Cycles : 16.9236 per block ( 28.26%) - 0.2644 per byte - 3.1565 per structural - 3.099 GHz est. frequency
|
||||
| Instructions : 56.5024 per block ( 30.28%) - 0.8829 per byte - 10.5383 per structural - 3.339 per cycle
|
||||
| Misses : 130 branch misses ( 20.32%) - 0 cache misses ( 0.00%) - 12365.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 13.4108 ns per block ( 69.19%) - 0.2096 ns per byte - 2.5013 ns per structural - 4.7721 GB/s
|
||||
| Cycles : 41.5073 per block ( 69.31%) - 0.6486 per byte - 7.7416 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 130.1221 per block ( 69.72%) - 2.0332 per byte - 24.2693 per structural - 3.135 per cycle
|
||||
| Misses : 489 branch misses ( 76.42%) - 0 cache misses ( 0.00%) - 16279.00 cache references
|
||||
|
||||
5119.7 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter1-emptystring.json
|
||||
======================================
|
||||
10306 blocks - 659626 bytes - 55262 structurals ( 8.4 %)
|
||||
special blocks with: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 1269 ( 12.3 %) - 1+ structurals 9038 ( 87.7 %) - 8+ structurals 2856 ( 27.7 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 928 ( 9.0 %) - 1+ structurals 928 ( 9.0 %) - 8+ structurals 3123 ( 30.3 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 18.0587 ns per block ( 93.58%) - 0.2822 ns per byte - 3.3682 ns per structural - 3.5439 GB/s
|
||||
| Cycles : 55.9116 per block ( 97.35%) - 0.8736 per byte - 10.4282 per structural - 3.096 GHz est. frequency
|
||||
| Instructions : 183.3181 per block (100.00%) - 2.8644 per byte - 34.1909 per structural - 3.279 per cycle
|
||||
| Misses : 473 branch misses (101.19%) - 1 cache misses ( 15.11%) - 18833.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 5.4026 ns per block ( 28.00%) - 0.0844 ns per byte - 1.0077 ns per structural - 11.8457 GB/s
|
||||
| Cycles : 16.7461 per block ( 29.16%) - 0.2617 per byte - 3.1233 per structural - 3.100 GHz est. frequency
|
||||
| Instructions : 56.5028 per block ( 30.82%) - 0.8829 per byte - 10.5384 per structural - 3.374 per cycle
|
||||
| Misses : 112 branch misses ( 23.96%) - 0 cache misses ( 0.00%) - 10717.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 12.6022 ns per block ( 65.30%) - 0.1969 ns per byte - 2.3505 ns per structural - 5.0783 GB/s
|
||||
| Cycles : 39.0031 per block ( 67.91%) - 0.6094 per byte - 7.2745 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 126.8154 per block ( 69.18%) - 1.9816 per byte - 23.6525 per structural - 3.251 per cycle
|
||||
| Misses : 351 branch misses ( 75.09%) - 1 cache misses ( 15.11%) - 8120.00 cache references
|
||||
|
||||
5372.6 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter-allstrings.json
|
||||
====================================
|
||||
10306 blocks - 659626 bytes - 55262 structurals ( 8.4 %)
|
||||
special blocks with: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 1269 ( 12.3 %) - 1+ structurals 9038 ( 87.7 %) - 8+ structurals 2853 ( 27.7 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 928 ( 9.0 %) - 1+ structurals 928 ( 9.0 %) - 8+ structurals 3107 ( 30.1 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 19.6482 ns per block ( 97.20%) - 0.3070 ns per byte - 3.6646 ns per structural - 3.2572 GB/s
|
||||
| Cycles : 60.8255 per block ( 97.62%) - 0.9504 per byte - 11.3446 per structural - 3.096 GHz est. frequency
|
||||
| Instructions : 183.8463 per block (100.00%) - 2.8727 per byte - 34.2895 per structural - 3.023 per cycle
|
||||
| Misses : 300 branch misses ( 96.97%) - 0 cache misses ( 0.00%) - 18361.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 5.4053 ns per block ( 26.74%) - 0.0845 ns per byte - 1.0081 ns per structural - 11.8399 GB/s
|
||||
| Cycles : 16.7545 per block ( 26.89%) - 0.2618 per byte - 3.1249 per structural - 3.100 GHz est. frequency
|
||||
| Instructions : 56.5028 per block ( 30.73%) - 0.8829 per byte - 10.5384 per structural - 3.372 per cycle
|
||||
| Misses : 98 branch misses ( 31.68%) - 1 cache misses ( 18.41%) - 10786.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 14.0367 ns per block ( 69.44%) - 0.2193 ns per byte - 2.6180 ns per structural - 4.5593 GB/s
|
||||
| Cycles : 43.4371 per block ( 69.71%) - 0.6787 per byte - 8.1015 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 127.3447 per block ( 69.27%) - 1.9898 per byte - 23.7513 per structural - 2.932 per cycle
|
||||
| Misses : 216 branch misses ( 69.82%) - 0 cache misses ( 0.00%) - 7835.00 cache references
|
||||
|
||||
4937.9 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter-allstrings-arrays.json
|
||||
===========================================
|
||||
10306 blocks - 659626 bytes - 55262 structurals ( 8.4 %)
|
||||
special blocks with: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 1269 ( 12.3 %) - 1+ structurals 9038 ( 87.7 %) - 8+ structurals 2853 ( 27.7 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 928 ( 9.0 %) - 1+ structurals 928 ( 9.0 %) - 8+ structurals 3107 ( 30.1 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 23.6768 ns per block ( 96.29%) - 0.3700 ns per byte - 4.4160 ns per structural - 2.7030 GB/s
|
||||
| Cycles : 72.7530 per block ( 95.79%) - 1.1368 per byte - 13.5693 per structural - 3.073 GHz est. frequency
|
||||
| Instructions : 225.0789 per block (100.00%) - 3.5170 per byte - 41.9798 per structural - 3.094 per cycle
|
||||
| Misses : 547 branch misses (104.38%) - 0 cache misses ( 0.00%) - 17259.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 5.4063 ns per block ( 21.99%) - 0.0845 ns per byte - 1.0083 ns per structural - 11.8376 GB/s
|
||||
| Cycles : 16.7598 per block ( 22.07%) - 0.2619 per byte - 3.1259 per structural - 3.100 GHz est. frequency
|
||||
| Instructions : 56.5028 per block ( 25.10%) - 0.8829 per byte - 10.5384 per structural - 3.371 per cycle
|
||||
| Misses : 101 branch misses ( 19.27%) - 0 cache misses ( 0.00%) - 10570.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 18.2062 ns per block ( 74.04%) - 0.2845 ns per byte - 3.3957 ns per structural - 3.5152 GB/s
|
||||
| Cycles : 55.7937 per block ( 73.46%) - 0.8718 per byte - 10.4062 per structural - 3.065 GHz est. frequency
|
||||
| Instructions : 168.5761 per block ( 74.90%) - 2.6341 per byte - 31.4414 per structural - 3.021 per cycle
|
||||
| Misses : 427 branch misses ( 81.48%) - 0 cache misses ( 0.00%) - 6797.00 cache references
|
||||
|
||||
4097.7 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter-allstrings-flatarray.json
|
||||
==============================================
|
||||
10306 blocks - 659626 bytes - 49890 structurals ( 7.6 %)
|
||||
special blocks with: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 1279 ( 12.4 %) - 1+ structurals 9028 ( 87.6 %) - 8+ structurals 2100 ( 20.4 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 946 ( 9.2 %) - 1+ structurals 946 ( 9.2 %) - 8+ structurals 2668 ( 25.9 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 20.5314 ns per block ( 98.77%) - 0.3208 ns per byte - 4.2417 ns per structural - 3.1171 GB/s
|
||||
| Cycles : 63.5535 per block ( 98.95%) - 0.9931 per byte - 13.1298 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 208.9967 per block (100.00%) - 3.2657 per byte - 43.1776 per structural - 3.289 per cycle
|
||||
| Misses : 94 branch misses ( 99.52%) - 0 cache misses ( 0.00%) - 15420.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 5.3985 ns per block ( 25.97%) - 0.0844 ns per byte - 1.1153 ns per structural - 11.8548 GB/s
|
||||
| Cycles : 16.7318 per block ( 26.05%) - 0.2614 per byte - 3.4567 per structural - 3.099 GHz est. frequency
|
||||
| Instructions : 56.4917 per block ( 27.03%) - 0.8827 per byte - 11.6709 per structural - 3.376 per cycle
|
||||
| Misses : 87 branch misses ( 92.11%) - 0 cache misses ( 0.00%) - 9889.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 15.0691 ns per block ( 72.49%) - 0.2355 ns per byte - 3.1132 ns per structural - 4.2470 GB/s
|
||||
| Cycles : 46.6318 per block ( 72.61%) - 0.7286 per byte - 9.6339 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 152.5050 per block ( 72.97%) - 2.3830 per byte - 31.5067 per structural - 3.270 per cycle
|
||||
| Misses : 3 branch misses ( 3.18%) - 0 cache misses ( 0.00%) - 5610.00 cache references
|
||||
|
||||
4725.5 documents parsed per second (best)
|
||||
|
||||
jsonexamples/twitter-allstrings-flatobjects.json
|
||||
================================================
|
||||
10306 blocks - 659626 bytes - 56091 structurals ( 8.5 %)
|
||||
special blocks with: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 1269 ( 12.3 %) - 1+ structurals 9038 ( 87.7 %) - 8+ structurals 2973 ( 28.8 %) - 16+ structurals 0 ( 0.0 %)
|
||||
special block flips: utf8 0 ( 0.0 %) - escape 0 ( 0.0 %) - 0 structurals 928 ( 9.0 %) - 1+ structurals 928 ( 9.0 %) - 8+ structurals 3093 ( 30.0 %) - 16+ structurals 0 ( 0.0 %)
|
||||
|
||||
All Stages (excluding allocation)
|
||||
| Speed : 19.4292 ns per block ( 97.71%) - 0.3036 ns per byte - 3.5702 ns per structural - 3.2939 GB/s
|
||||
| Cycles : 60.1577 per block ( 97.90%) - 0.9400 per byte - 11.0543 per structural - 3.096 GHz est. frequency
|
||||
| Instructions : 181.6747 per block (100.00%) - 2.8388 per byte - 33.3836 per structural - 3.020 per cycle
|
||||
| Misses : 508 branch misses (100.57%) - 0 cache misses ( 0.00%) - 17421.00 cache references
|
||||
|- Stage 1
|
||||
| Speed : 5.4138 ns per block ( 27.22%) - 0.0846 ns per byte - 0.9948 ns per structural - 11.8213 GB/s
|
||||
| Cycles : 16.7833 per block ( 27.31%) - 0.2622 per byte - 3.0840 per structural - 3.100 GHz est. frequency
|
||||
| Instructions : 56.5028 per block ( 31.10%) - 0.8829 per byte - 10.3827 per structural - 3.367 per cycle
|
||||
| Misses : 99 branch misses ( 19.60%) - 0 cache misses ( 0.00%) - 10517.00 cache references
|
||||
|- Stage 2
|
||||
| Speed : 13.9445 ns per block ( 70.12%) - 0.2179 ns per byte - 2.5624 ns per structural - 4.5895 GB/s
|
||||
| Cycles : 43.1562 per block ( 70.23%) - 0.6743 per byte - 7.9302 per structural - 3.095 GHz est. frequency
|
||||
| Instructions : 125.1719 per block ( 68.90%) - 1.9559 per byte - 23.0010 per structural - 2.900 per cycle
|
||||
| Misses : 402 branch misses ( 79.59%) - 0 cache misses ( 0.00%) - 6973.00 cache references
|
||||
|
||||
4993.6 documents parsed per second (best)
|
||||
|
||||
@@ -224,7 +224,8 @@ private:
|
||||
* Parse the next document found in the buffer previously given to document_stream.
|
||||
*
|
||||
* The content should be a valid JSON document encoded as UTF-8. If there is a
|
||||
* UTF-8 BOM, the parser skips it.
|
||||
* UTF-8 BOM, the caller is responsible for omitting it, UTF-8 BOM are
|
||||
* discouraged.
|
||||
*
|
||||
* You do NOT need to pre-allocate a parser. This function takes care of
|
||||
* pre-allocating a capacity defined by the batch_size defined when creating the
|
||||
|
||||
@@ -410,12 +410,6 @@ inline simdjson_result<element> element::at_key(std::string_view key) const noex
|
||||
inline simdjson_result<element> element::at_key_case_insensitive(std::string_view key) const noexcept {
|
||||
return get<object>().at_key_case_insensitive(key);
|
||||
}
|
||||
inline bool element::operator<(const element &other) const noexcept {
|
||||
return tape.json_index < other.tape.json_index;
|
||||
}
|
||||
inline bool element::operator==(const element &other) const noexcept {
|
||||
return tape.json_index == other.tape.json_index;
|
||||
}
|
||||
|
||||
inline bool element::dump_raw_tape(std::ostream &out) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
|
||||
@@ -211,11 +211,7 @@ public:
|
||||
inline simdjson_result<T> get() const noexcept {
|
||||
// Unless the simdjson library provides an inline implementation, calling this method should
|
||||
// immediately fail.
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
|
||||
"The supported types are Boolean (bool), numbers (double, uint64_t, int64_t), "
|
||||
"strings (std::string_view, const char *), arrays (dom::array) and objects (dom::object). "
|
||||
"We recommand you use get_double(), get_bool(), get_uint64(), get_int64(), "
|
||||
"get_object(), get_array() or get_string() instead of the get template.");
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -455,22 +451,6 @@ public:
|
||||
*/
|
||||
inline simdjson_result<element> at_key_case_insensitive(std::string_view key) const noexcept;
|
||||
|
||||
/**
|
||||
* operator< defines a total order for element allowing to use them in
|
||||
* ordered C++ STL containers
|
||||
*
|
||||
* @return TRUE if the key appears before the other one in the tape
|
||||
*/
|
||||
inline bool operator<(const element &other) const noexcept;
|
||||
|
||||
/**
|
||||
* operator== allows to verify if two element values reference the
|
||||
* same JSON item
|
||||
*
|
||||
* @return TRUE if the two values references the same JSON element
|
||||
*/
|
||||
inline bool operator==(const element &other) const noexcept;
|
||||
|
||||
/** @private for debugging. Prints out the root element. */
|
||||
inline bool dump_raw_tape(std::ostream &out) const noexcept;
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "simdjson/dom/element-inl.h"
|
||||
|
||||
#include <climits>
|
||||
#include <cstring> /* memcmp */
|
||||
|
||||
namespace simdjson {
|
||||
namespace dom {
|
||||
@@ -121,14 +120,8 @@ inline simdjson_result<element> parser::parse_into_document(document& provided_d
|
||||
_loaded_bytes_capacity = len;
|
||||
}
|
||||
std::memcpy(static_cast<void *>(loaded_bytes.get()), buf, len);
|
||||
buf = reinterpret_cast<const uint8_t*>(loaded_bytes.get());
|
||||
}
|
||||
|
||||
if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) {
|
||||
buf += 3;
|
||||
len -= 3;
|
||||
}
|
||||
_error = implementation->parse(buf, len, provided_doc);
|
||||
_error = implementation->parse(realloc_if_needed ? reinterpret_cast<const uint8_t*>(loaded_bytes.get()): buf, len, provided_doc);
|
||||
|
||||
if (_error) { return _error; }
|
||||
|
||||
@@ -165,10 +158,6 @@ simdjson_inline simdjson_result<element> parser::parse(const padded_string_view
|
||||
|
||||
inline simdjson_result<document_stream> parser::parse_many(const uint8_t *buf, size_t len, size_t batch_size) noexcept {
|
||||
if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; }
|
||||
if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) {
|
||||
buf += 3;
|
||||
len -= 3;
|
||||
}
|
||||
return document_stream(*this, buf, len, batch_size);
|
||||
}
|
||||
inline simdjson_result<document_stream> parser::parse_many(const char *buf, size_t len, size_t batch_size) noexcept {
|
||||
|
||||
@@ -254,8 +254,6 @@ public:
|
||||
* And, possibly, no document many have been parsed when the `parser.load_many(path)` function
|
||||
* returned.
|
||||
*
|
||||
* If there is a UTF-8 BOM, the parser skips it.
|
||||
*
|
||||
* ### Format
|
||||
*
|
||||
* The file must contain a series of one or more JSON documents, concatenated into a single
|
||||
@@ -348,8 +346,6 @@ public:
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
* }
|
||||
*
|
||||
* If there is a UTF-8 BOM, the parser skips it.
|
||||
*
|
||||
* ### Format
|
||||
*
|
||||
* The buffer must contain a series of one or more JSON documents, concatenated into a single
|
||||
|
||||
@@ -128,10 +128,6 @@ simdjson_inline simdjson_result<double> document::get_double_in_string() noexcep
|
||||
simdjson_inline simdjson_result<std::string_view> document::get_string(bool allow_replacement) noexcept {
|
||||
return get_root_value_iterator().get_root_string(true, allow_replacement);
|
||||
}
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code document::get_string(string_type& receiver, bool allow_replacement) noexcept {
|
||||
return get_root_value_iterator().get_root_string(receiver, true, allow_replacement);
|
||||
}
|
||||
simdjson_inline simdjson_result<std::string_view> document::get_wobbly_string() noexcept {
|
||||
return get_root_value_iterator().get_root_wobbly_string(true);
|
||||
}
|
||||
@@ -401,11 +397,6 @@ simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLE
|
||||
if (error()) { return error(); }
|
||||
return first.get_string(allow_replacement);
|
||||
}
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_string(string_type& receiver, bool allow_replacement) noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_string(receiver, allow_replacement);
|
||||
}
|
||||
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_wobbly_string() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_wobbly_string();
|
||||
@@ -592,8 +583,6 @@ simdjson_inline simdjson_result<int64_t> document_reference::get_int64_in_string
|
||||
simdjson_inline simdjson_result<double> document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
|
||||
simdjson_inline simdjson_result<double> document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
|
||||
simdjson_inline simdjson_result<std::string_view> document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); }
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code document_reference::get_string(string_type& receiver, bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(receiver, false, allow_replacement); }
|
||||
simdjson_inline simdjson_result<std::string_view> document_reference::get_wobbly_string() noexcept { return doc->get_root_value_iterator().get_root_wobbly_string(false); }
|
||||
simdjson_inline simdjson_result<raw_json_string> document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); }
|
||||
simdjson_inline simdjson_result<bool> document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); }
|
||||
@@ -730,11 +719,6 @@ simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLE
|
||||
if (error()) { return error(); }
|
||||
return first.get_string(allow_replacement);
|
||||
}
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_string(string_type& receiver, bool allow_replacement) noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_string(receiver, allow_replacement);
|
||||
}
|
||||
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_wobbly_string() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_wobbly_string();
|
||||
|
||||
@@ -100,21 +100,6 @@ public:
|
||||
* @returns INCORRECT_TYPE if the JSON value is not a string.
|
||||
*/
|
||||
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
|
||||
/**
|
||||
* Attempts to fill the provided std::string reference with the parsed value of the current string.
|
||||
*
|
||||
* The string is guaranteed to be valid UTF-8.
|
||||
*
|
||||
* Important: a value should be consumed once. Calling get_string() twice on the same value
|
||||
* is an error.
|
||||
*
|
||||
* Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory.
|
||||
* We recommend you avoid allocating an std::string unless you need to.
|
||||
*
|
||||
* @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS.
|
||||
*/
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept;
|
||||
/**
|
||||
* Cast this JSON value to a string.
|
||||
*
|
||||
@@ -175,19 +160,13 @@ public:
|
||||
template<typename T> simdjson_inline simdjson_result<T> get() & noexcept {
|
||||
// Unless the simdjson library provides an inline implementation, calling this method should
|
||||
// immediately fail.
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
|
||||
"The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, "
|
||||
"int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), "
|
||||
" get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template.");
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
|
||||
}
|
||||
/** @overload template<typename T> simdjson_result<T> get() & noexcept */
|
||||
template<typename T> simdjson_inline simdjson_result<T> get() && noexcept {
|
||||
// Unless the simdjson library provides an inline implementation, calling this method should
|
||||
// immediately fail.
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
|
||||
"The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, "
|
||||
"int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), "
|
||||
" get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template.");
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -639,8 +618,6 @@ public:
|
||||
simdjson_inline simdjson_result<double> get_double() noexcept;
|
||||
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
|
||||
simdjson_inline simdjson_result<raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
@@ -710,8 +687,6 @@ public:
|
||||
simdjson_inline simdjson_result<double> get_double() noexcept;
|
||||
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
@@ -784,8 +759,6 @@ public:
|
||||
simdjson_inline simdjson_result<double> get_double() noexcept;
|
||||
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
|
||||
@@ -241,7 +241,8 @@ private:
|
||||
* Parse the next document found in the buffer previously given to document_stream.
|
||||
*
|
||||
* The content should be a valid JSON document encoded as UTF-8. If there is a
|
||||
* UTF-8 BOM, the parser skips it.
|
||||
* UTF-8 BOM, the caller is responsible for omitting it, UTF-8 BOM are
|
||||
* discouraged.
|
||||
*
|
||||
* You do NOT need to pre-allocate a parser. This function takes care of
|
||||
* pre-allocating a capacity defined by the batch_size defined when creating the
|
||||
|
||||
@@ -254,7 +254,6 @@ public:
|
||||
*/
|
||||
simdjson_inline simdjson_result<std::string_view> unescape(raw_json_string in, bool allow_replacement) noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> unescape_wobbly(raw_json_string in) noexcept;
|
||||
|
||||
simdjson_inline void reenter_child(token_position position, depth_t child_depth) noexcept;
|
||||
|
||||
simdjson_inline error_code consume_character(char c) noexcept;
|
||||
|
||||
@@ -46,8 +46,6 @@ simdjson_warn_unused simdjson_inline error_code parser::allocate(size_t new_capa
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(padded_string_view json) & noexcept {
|
||||
if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; }
|
||||
|
||||
json.remove_utf8_bom();
|
||||
|
||||
// Allocate if needed
|
||||
if (capacity() < json.length() || !string_buf) {
|
||||
SIMDJSON_TRY( allocate(json.length(), max_depth()) );
|
||||
@@ -70,13 +68,6 @@ simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(s
|
||||
return iterate(padded_string_view(json, allocated));
|
||||
}
|
||||
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(std::string &json) & noexcept {
|
||||
if(json.capacity() - json.size() < SIMDJSON_PADDING) {
|
||||
json.reserve(json.size() + SIMDJSON_PADDING);
|
||||
}
|
||||
return iterate(padded_string_view(json));
|
||||
}
|
||||
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(const std::string &json) & noexcept {
|
||||
return iterate(padded_string_view(json));
|
||||
}
|
||||
@@ -98,8 +89,6 @@ simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(c
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<json_iterator> parser::iterate_raw(padded_string_view json) & noexcept {
|
||||
if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; }
|
||||
|
||||
json.remove_utf8_bom();
|
||||
|
||||
// Allocate if needed
|
||||
if (capacity() < json.length()) {
|
||||
SIMDJSON_TRY( allocate(json.length(), max_depth()) );
|
||||
@@ -112,10 +101,6 @@ simdjson_warn_unused simdjson_inline simdjson_result<json_iterator> parser::iter
|
||||
|
||||
inline simdjson_result<document_stream> parser::iterate_many(const uint8_t *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept {
|
||||
if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; }
|
||||
if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) {
|
||||
buf += 3;
|
||||
len -= 3;
|
||||
}
|
||||
if(allow_comma_separated && batch_size < len) { batch_size = len; }
|
||||
return document_stream(*this, buf, len, batch_size, allow_comma_separated);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
* It is expected that the content is a valid UTF-8 file, containing a valid JSON document.
|
||||
* Otherwise the iterate method may return an error. In particular, the whole input should be
|
||||
* valid: we do not attempt to tolerate incorrect content either before or after a JSON
|
||||
* document. If there is a UTF-8 BOM, the parser skips it.
|
||||
* document.
|
||||
*
|
||||
* ### IMPORTANT: Validate what you use
|
||||
*
|
||||
@@ -107,8 +107,6 @@ public:
|
||||
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
|
||||
simdjson_warn_unused simdjson_result<document> iterate(const std::string &json) & noexcept;
|
||||
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
|
||||
simdjson_warn_unused simdjson_result<document> iterate(std::string &json) & noexcept;
|
||||
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
|
||||
simdjson_warn_unused simdjson_result<document> iterate(const simdjson_result<padded_string> &json) & noexcept;
|
||||
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
|
||||
simdjson_warn_unused simdjson_result<document> iterate(const simdjson_result<padded_string_view> &json) & noexcept;
|
||||
@@ -188,7 +186,6 @@ public:
|
||||
* arrays or objects) MUST be separated with ASCII whitespace.
|
||||
*
|
||||
* The characters inside a JSON document, and between JSON documents, must be valid Unicode (UTF-8).
|
||||
* If there is a UTF-8 BOM, the parser skips it.
|
||||
*
|
||||
* The documents must not exceed batch_size bytes (by default 1MB) or they will fail to parse.
|
||||
* Setting batch_size to excessively large or excessively small values may impact negatively the
|
||||
|
||||
@@ -47,10 +47,6 @@ simdjson_inline simdjson_result<raw_json_string> value::get_raw_json_string() no
|
||||
simdjson_inline simdjson_result<std::string_view> value::get_string(bool allow_replacement) noexcept {
|
||||
return iter.get_string(allow_replacement);
|
||||
}
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code value::get_string(string_type& receiver, bool allow_replacement) noexcept {
|
||||
return iter.get_string(receiver, allow_replacement);
|
||||
}
|
||||
simdjson_inline simdjson_result<std::string_view> value::get_wobbly_string() noexcept {
|
||||
return iter.get_wobbly_string();
|
||||
}
|
||||
@@ -197,26 +193,6 @@ simdjson_inline std::string_view value::raw_json_token() noexcept {
|
||||
return std::string_view(reinterpret_cast<const char*>(iter.peek_start()), iter.peek_start_length());
|
||||
}
|
||||
|
||||
simdjson_inline simdjson_result<std::string_view> value::raw_json() noexcept {
|
||||
json_type t;
|
||||
SIMDJSON_TRY(type().get(t));
|
||||
switch (t)
|
||||
{
|
||||
case json_type::array: {
|
||||
ondemand::array array;
|
||||
SIMDJSON_TRY(get_array().get(array));
|
||||
return array.raw_json();
|
||||
}
|
||||
case json_type::object: {
|
||||
ondemand::object object;
|
||||
SIMDJSON_TRY(get_object().get(object));
|
||||
return object.raw_json();
|
||||
}
|
||||
default:
|
||||
return raw_json_token();
|
||||
}
|
||||
}
|
||||
|
||||
simdjson_inline simdjson_result<const char *> value::current_location() noexcept {
|
||||
return iter.json_iter().current_location();
|
||||
}
|
||||
@@ -343,11 +319,6 @@ simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLE
|
||||
if (error()) { return error(); }
|
||||
return first.get_string(allow_replacement);
|
||||
}
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_string(string_type& receiver, bool allow_replacement) noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_string(receiver, allow_replacement);
|
||||
}
|
||||
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_wobbly_string() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_wobbly_string();
|
||||
@@ -448,11 +419,6 @@ simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLE
|
||||
return first.raw_json_token();
|
||||
}
|
||||
|
||||
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::raw_json() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.raw_json();
|
||||
}
|
||||
|
||||
simdjson_inline simdjson_result<const char *> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::current_location() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.current_location();
|
||||
|
||||
@@ -38,10 +38,7 @@ public:
|
||||
template<typename T> simdjson_inline simdjson_result<T> get() noexcept {
|
||||
// Unless the simdjson library provides an inline implementation, calling this method should
|
||||
// immediately fail.
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
|
||||
"The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, "
|
||||
"int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), "
|
||||
" get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template.");
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,21 +132,6 @@ public:
|
||||
*/
|
||||
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
|
||||
|
||||
/**
|
||||
* Attempts to fill the provided std::string reference with the parsed value of the current string.
|
||||
*
|
||||
* The string is guaranteed to be valid UTF-8.
|
||||
*
|
||||
* Important: a value should be consumed once. Calling get_string() twice on the same value
|
||||
* is an error.
|
||||
*
|
||||
* Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory.
|
||||
* We recommend you avoid allocating an std::string unless you need to.
|
||||
*
|
||||
* @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS.
|
||||
*/
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept;
|
||||
|
||||
/**
|
||||
* Cast this JSON value to a "wobbly" string.
|
||||
@@ -493,21 +475,9 @@ public:
|
||||
* - true
|
||||
* - false
|
||||
* - null
|
||||
*
|
||||
* See also value::raw_json().
|
||||
*/
|
||||
simdjson_inline std::string_view raw_json_token() noexcept;
|
||||
|
||||
/**
|
||||
* Get a string_view pointing at this value in the JSON document.
|
||||
* If this element is an array or an object, it consumes the array or the object
|
||||
* and returns a string_view instance corresponding to the
|
||||
* array as represented in JSON. It points inside the original document.
|
||||
* If this element is a scalar (string, number, Boolean, null), it returns what
|
||||
* raw_json_token() would return.
|
||||
*/
|
||||
simdjson_inline simdjson_result<std::string_view> raw_json() noexcept;
|
||||
|
||||
/**
|
||||
* Returns the current location in the document if in bounds.
|
||||
*/
|
||||
@@ -632,8 +602,6 @@ public:
|
||||
simdjson_inline simdjson_result<double> get_double() noexcept;
|
||||
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
|
||||
template <typename string_type>
|
||||
simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
@@ -726,7 +694,6 @@ public:
|
||||
|
||||
/** @copydoc simdjson_inline std::string_view value::raw_json_token() const noexcept */
|
||||
simdjson_inline simdjson_result<std::string_view> raw_json_token() noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> raw_json() noexcept;
|
||||
|
||||
/** @copydoc simdjson_inline simdjson_result<const char *> current_location() noexcept */
|
||||
simdjson_inline simdjson_result<const char *> current_location() noexcept;
|
||||
|
||||
@@ -513,14 +513,6 @@ simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::parse
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_string(bool allow_replacement) noexcept {
|
||||
return get_raw_json_string().unescape(json_iter(), allow_replacement);
|
||||
}
|
||||
template <typename string_type>
|
||||
simdjson_warn_unused simdjson_inline error_code value_iterator::get_string(string_type& receiver, bool allow_replacement) noexcept {
|
||||
std::string_view content;
|
||||
auto err = get_string(allow_replacement).get(content);
|
||||
if (err) { return err; }
|
||||
receiver = content;
|
||||
return SUCCESS;
|
||||
}
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_wobbly_string() noexcept {
|
||||
return get_raw_json_string().unescape_wobbly(json_iter());
|
||||
}
|
||||
@@ -644,14 +636,6 @@ simdjson_inline simdjson_result<number> value_iterator::get_root_number(bool che
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_root_string(bool check_trailing, bool allow_replacement) noexcept {
|
||||
return get_root_raw_json_string(check_trailing).unescape(json_iter(), allow_replacement);
|
||||
}
|
||||
template <typename string_type>
|
||||
simdjson_warn_unused simdjson_inline error_code value_iterator::get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept {
|
||||
std::string_view content;
|
||||
auto err = get_root_string(check_trailing, allow_replacement).get(content);
|
||||
if (err) { return err; }
|
||||
receiver = content;
|
||||
return SUCCESS;
|
||||
}
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_root_wobbly_string(bool check_trailing) noexcept {
|
||||
return get_root_raw_json_string(check_trailing).unescape_wobbly(json_iter());
|
||||
}
|
||||
|
||||
@@ -296,8 +296,6 @@ public:
|
||||
*/
|
||||
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement) noexcept;
|
||||
template <typename string_type>
|
||||
simdjson_warn_unused simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement) noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
|
||||
@@ -314,9 +312,7 @@ public:
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<number> get_number() noexcept;
|
||||
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> get_root_string(bool check_trailing, bool allow_replacement) noexcept;
|
||||
template <typename string_type>
|
||||
simdjson_warn_unused simdjson_inline error_code get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> get_root_wobbly_string(bool check_trailing) noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> get_root_wobbly_string(bool check_trailing) noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> get_root_raw_json_string(bool check_trailing) noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64(bool check_trailing) noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64_in_string(bool check_trailing) noexcept;
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
#define SIMDJSON_PADDED_STRING_VIEW_INL_H
|
||||
|
||||
#include "simdjson/padded_string_view.h"
|
||||
#include "simdjson/error-inl.h"
|
||||
|
||||
#include <cstring> /* memcmp */
|
||||
#include "simdjson/error-inl.h"
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
@@ -32,16 +31,6 @@ inline size_t padded_string_view::capacity() const noexcept { return _capacity;
|
||||
|
||||
inline size_t padded_string_view::padding() const noexcept { return capacity() - length(); }
|
||||
|
||||
inline bool padded_string_view::remove_utf8_bom() noexcept {
|
||||
if(length() < 3) { return false; }
|
||||
if (std::memcmp(data(), "\xEF\xBB\xBF", 3) == 0) {
|
||||
remove_prefix(3);
|
||||
_capacity -= 3;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
inline std::ostream& operator<<(std::ostream& out, simdjson_result<padded_string_view> &s) noexcept(false) { return out << s.value(); }
|
||||
#endif
|
||||
|
||||
@@ -54,13 +54,6 @@ public:
|
||||
/** The number of allocated bytes. */
|
||||
inline size_t capacity() const noexcept;
|
||||
|
||||
/**
|
||||
* Remove the UTF-8 Byte Order Mark (BOM) if it exists.
|
||||
*
|
||||
* @return whether a BOM was found and removed
|
||||
*/
|
||||
inline bool remove_utf8_bom() noexcept;
|
||||
|
||||
/** The amount of padding on the string (capacity() - length()) */
|
||||
inline size_t padding() const noexcept;
|
||||
|
||||
|
||||
@@ -58,8 +58,11 @@
|
||||
|
||||
#if SIMDJSON_IS_32BITS
|
||||
#ifndef SIMDJSON_NO_PORTABILITY_WARNING
|
||||
// In the future, we should allow programmers
|
||||
// to get warning.
|
||||
#pragma message("The simdjson library is designed \
|
||||
for 64-bit processors and it seems that you are not \
|
||||
compiling for a known 64-bit platform. All fast kernels \
|
||||
will be disabled and performance may be poor. Please \
|
||||
use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.")
|
||||
#endif // SIMDJSON_NO_PORTABILITY_WARNING
|
||||
#endif // SIMDJSON_IS_32BITS
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||
|
||||
/** The version of simdjson being used (major.minor.revision) */
|
||||
#define SIMDJSON_VERSION "3.6.0"
|
||||
#define SIMDJSON_VERSION "3.2.3"
|
||||
|
||||
namespace simdjson {
|
||||
enum {
|
||||
@@ -15,11 +15,11 @@ enum {
|
||||
/**
|
||||
* The minor version (major.MINOR.revision) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_MINOR = 6,
|
||||
SIMDJSON_VERSION_MINOR = 2,
|
||||
/**
|
||||
* The revision (major.minor.REVISION) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_REVISION = 0
|
||||
SIMDJSON_VERSION_REVISION = 3
|
||||
};
|
||||
} // namespace simdjson
|
||||
|
||||
|
||||
Executable
+263
@@ -0,0 +1,263 @@
|
||||
from itertools import groupby
|
||||
from pathlib import Path
|
||||
from typing import Any, Iterable, Literal, Optional, OrderedDict, cast
|
||||
from io import BufferedWriter, BufferedReader
|
||||
import re
|
||||
import sys
|
||||
|
||||
ContainerState = Literal['orig', 'array', 'flat']
|
||||
ScalarState = Literal['orig', '1digit', 'str']
|
||||
StringState = Literal['orig', 'unescaped', 'ascii', 'empty']
|
||||
CONTAINER_STATES: list[ContainerState] = ['orig', 'array', 'flat']
|
||||
SCALAR_STATES: list[ScalarState] = ['orig', '1digit', 'str']
|
||||
STRING_STATES: list[StringState] = ['orig', 'unescaped', 'ascii', 'empty']
|
||||
|
||||
class Result:
|
||||
class Metric:
|
||||
def __init__(self, name: str, value: float, units: str):
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.units = units
|
||||
|
||||
def best(self, other: 'Result.Metric'):
|
||||
assert self.name == other.name
|
||||
assert self.units == other.units
|
||||
if self.name == 'Speed':
|
||||
return self if self.value > other.value else other
|
||||
else:
|
||||
return self if self.value < other.value else other
|
||||
|
||||
class Stage:
|
||||
def __init__(self, stage: str):
|
||||
self.stage = stage
|
||||
self.metrics: dict[str, Result.Metric] = {}
|
||||
|
||||
@property
|
||||
def speed(self):
|
||||
return self.metrics['Speed']
|
||||
|
||||
@property
|
||||
def cycles(self):
|
||||
return self.metrics['Cycles']
|
||||
|
||||
@property
|
||||
def instructions(self):
|
||||
return self.metrics['Instructions']
|
||||
|
||||
@property
|
||||
def misses(self):
|
||||
return self.metrics['Misses']
|
||||
|
||||
def _merge_in(self, other: 'Result.Stage'):
|
||||
assert self.stage == other.stage
|
||||
for metric in other.metrics.values():
|
||||
if metric.name not in self.metrics:
|
||||
self.metrics[metric.name] = metric
|
||||
self.metrics[metric.name] = self.metrics[metric.name].best(metric)
|
||||
|
||||
def __init__(self, json_file: Path):
|
||||
self.json_file = json_file
|
||||
self.stages = dict[str, Result.Stage]()
|
||||
match = re.match(r'(.*)-([^-]*)-([^-]*)-([^-]*)$', json_file.stem)
|
||||
if match:
|
||||
self.base_json_file = match.group(1)
|
||||
assert match.group(2) in CONTAINER_STATES
|
||||
self.container_state: ContainerState = cast(ContainerState, match.group(2))
|
||||
assert match.group(3) in SCALAR_STATES
|
||||
self.scalar_state: ScalarState = cast(ScalarState, match.group(3))
|
||||
assert match.group(4) in STRING_STATES
|
||||
self.string_state: StringState = cast(StringState, match.group(4))
|
||||
else:
|
||||
self.base_json_file = self.json_file.stem
|
||||
self.container_state = 'orig'
|
||||
self.scalar_state = 'orig'
|
||||
self.string_state = 'orig'
|
||||
self.docs_per_second: float = -1
|
||||
|
||||
def __lt__(self, other: 'Result'):
|
||||
if self.base_json_file != other.base_json_file:
|
||||
return self.base_json_file < other.base_json_file
|
||||
if self.container_state != other.container_state:
|
||||
return CONTAINER_STATES.index(self.container_state) < CONTAINER_STATES.index(other.container_state)
|
||||
if self.scalar_state != other.scalar_state:
|
||||
return SCALAR_STATES.index(self.scalar_state) < SCALAR_STATES.index(other.scalar_state)
|
||||
if self.string_state != other.string_state:
|
||||
return STRING_STATES.index(self.string_state) < STRING_STATES.index(other.string_state)
|
||||
return False
|
||||
|
||||
def merge(self, other: 'Result'):
|
||||
merged = Result(self.json_file)
|
||||
merged._merge_in(self)
|
||||
merged._merge_in(other)
|
||||
return merged
|
||||
|
||||
def _merge_in(self, other: 'Result'):
|
||||
assert self.json_file == other.json_file
|
||||
if other.docs_per_second > self.docs_per_second:
|
||||
self.docs_per_second = other.docs_per_second
|
||||
for stage in other.stages.values():
|
||||
if stage.stage not in self.stages:
|
||||
self.stages[stage.stage] = Result.Stage(stage.stage)
|
||||
self.stages[stage.stage]._merge_in(stage)
|
||||
|
||||
@property
|
||||
def stage1(self):
|
||||
return self.stages['Stage 1']
|
||||
|
||||
@property
|
||||
def stage2(self):
|
||||
return self.stages['Stage 2']
|
||||
|
||||
def read_results(results_file: Path):
|
||||
with open(result_file, 'rt') as input:
|
||||
result = None
|
||||
stage = None
|
||||
|
||||
prev_line = None
|
||||
for line in input:
|
||||
if re.match(r'=+$', line):
|
||||
assert result is None
|
||||
assert prev_line is not None
|
||||
result = Result(Path(prev_line.strip()))
|
||||
|
||||
# Stage
|
||||
match = re.match(r'\|-(.+)$', line)
|
||||
if match:
|
||||
assert result is not None
|
||||
stage = Result.Stage(match.group(1).strip())
|
||||
result.stages[stage.stage] = stage
|
||||
|
||||
# Metrics
|
||||
if stage is not None:
|
||||
match = re.match(r'\|([^:]+):\s*([-+0-9.]+)\s+([^(-]+)', line)
|
||||
if match and stage is not None:
|
||||
metric = Result.Metric(match.group(1).strip(), float(match.group(2)), match.group(3).strip())
|
||||
stage.metrics[metric.name] = metric
|
||||
|
||||
# Documents per second
|
||||
match = re.match(r'\s*([-+0-9.]+)\s*documents parsed per second', line)
|
||||
if match:
|
||||
assert result is not None
|
||||
result.docs_per_second = float(match.group(1))
|
||||
yield result
|
||||
result = None
|
||||
stage = None
|
||||
|
||||
prev_line = line
|
||||
|
||||
# Merge multiple results for the same file
|
||||
all_results = dict[Path, Result]()
|
||||
for result_file in sys.argv[1:]:
|
||||
for result in read_results(Path(result_file)):
|
||||
if result.json_file in all_results:
|
||||
all_results[result.json_file] = all_results[result.json_file].merge(result)
|
||||
else:
|
||||
all_results[result.json_file] = result
|
||||
|
||||
def print_row(row: Iterable, key_lengths: OrderedDict[str, int], rjust: set[str]):
|
||||
column_iter = iter(row)
|
||||
for (key, width) in key_lengths.items():
|
||||
value = str(next(column_iter))
|
||||
if key in rjust:
|
||||
print(f"| {str(value).rjust(width)} ", end='')
|
||||
else:
|
||||
print(f"| {str(value).ljust(width)} ", end='')
|
||||
print("|")
|
||||
|
||||
def print_table(rows: list[OrderedDict], key_lengths: Optional[OrderedDict[str, int]] = None, rjust = set[str]()):
|
||||
if key_lengths is None:
|
||||
key_lengths = OrderedDict[str, int]()
|
||||
for entry in rows:
|
||||
for (key, value) in entry.items():
|
||||
if key not in key_lengths:
|
||||
key_lengths[key] = len(key)
|
||||
key_lengths[key] = max(key_lengths[key], len(str(value)))
|
||||
|
||||
print_row(list(key_lengths.keys()), key_lengths, rjust)
|
||||
print("|", *[ f"{(':' if key in rjust else '').rjust(len+2, '-')}|" for (key, len) in key_lengths.items() ], sep='')
|
||||
|
||||
for row in rows:
|
||||
print_row(row.values(), key_lengths, rjust)
|
||||
|
||||
for (file, results) in groupby(sorted(all_results.values()), lambda r: r.base_json_file):
|
||||
results = [*results]
|
||||
print()
|
||||
print(f"# {file}.json Branch Miss Variants")
|
||||
print()
|
||||
print_table(
|
||||
[
|
||||
OrderedDict([
|
||||
('Contain', result.container_state),
|
||||
('Scalars', result.scalar_state),
|
||||
('Strings', result.string_state),
|
||||
('Cycles', '%.4f' % result.stage2.cycles.value),
|
||||
('Instrs', '%.4f' % result.stage2.instructions.value),
|
||||
('Misses', int(result.stage2.misses.value)),
|
||||
('Docs/sec', '%.1f' % result.docs_per_second),
|
||||
])
|
||||
for result in results
|
||||
],
|
||||
rjust = set(['Cycles', 'Instrs', 'Misses', 'Docs/sec'])
|
||||
)
|
||||
misses = {
|
||||
(r.container_state, r.scalar_state, r.string_state): int(r.stage2.misses.value)
|
||||
for r in results
|
||||
}
|
||||
|
||||
print()
|
||||
print('## Container State Transition Miss Reduction')
|
||||
print()
|
||||
rows = list[OrderedDict[str, object]]()
|
||||
PRINT_STRING_STATES: list[StringState] = [s for s in STRING_STATES if s != 'unescaped']
|
||||
for (i,from_state) in enumerate(CONTAINER_STATES[0:-1]):
|
||||
for to_state in CONTAINER_STATES[i+1:]:
|
||||
rows.append(OrderedDict([
|
||||
('Contain', f"{from_state} -> {to_state}"),
|
||||
*[
|
||||
(
|
||||
f"{scalar_state} {string_state}",
|
||||
misses[(from_state, scalar_state, string_state)] - misses[(to_state, scalar_state, string_state)]
|
||||
)
|
||||
for scalar_state in SCALAR_STATES
|
||||
for string_state in PRINT_STRING_STATES
|
||||
]
|
||||
]))
|
||||
print_table(rows, rjust = [*rows[0].keys()][1:])
|
||||
|
||||
print()
|
||||
print('## Scalar State Transition Miss Reduction')
|
||||
print()
|
||||
rows = list[OrderedDict[str, object]]()
|
||||
for (i,from_state) in enumerate(SCALAR_STATES[0:-1]):
|
||||
for to_state in SCALAR_STATES[i+1:]:
|
||||
rows.append(OrderedDict([
|
||||
('Scalars', f"{from_state} -> {to_state}"),
|
||||
*[
|
||||
(
|
||||
f"{container_state} {string_state}",
|
||||
misses[(container_state, from_state, string_state)] - misses[(container_state, to_state, string_state)]
|
||||
)
|
||||
for container_state in CONTAINER_STATES
|
||||
for string_state in PRINT_STRING_STATES
|
||||
]
|
||||
]))
|
||||
print_table(rows, rjust = [*rows[0].keys()][1:])
|
||||
|
||||
print()
|
||||
print('## String State Transition Miss Reduction')
|
||||
print()
|
||||
rows = list[OrderedDict[str, object]]()
|
||||
for (i,from_state) in enumerate(STRING_STATES[0:-1]):
|
||||
for to_state in STRING_STATES[i+1:]:
|
||||
rows.append(OrderedDict([
|
||||
('Strings', f"{from_state} -> {to_state}"),
|
||||
*[
|
||||
(
|
||||
f"{container_state} {scalar_state}",
|
||||
misses[(container_state, scalar_state, from_state)] - misses[(container_state, scalar_state, to_state)]
|
||||
)
|
||||
for container_state in CONTAINER_STATES
|
||||
for scalar_state in SCALAR_STATES
|
||||
]
|
||||
]))
|
||||
print_table(rows, rjust = [*rows[0].keys()][1:])
|
||||
Executable
+170
@@ -0,0 +1,170 @@
|
||||
from pathlib import Path
|
||||
from typing import Literal
|
||||
from io import BufferedWriter, BufferedReader
|
||||
import re
|
||||
import sys
|
||||
|
||||
ContainerState = Literal['orig', 'array', 'flat']
|
||||
ScalarState = Literal['orig', '1digit', 'str']
|
||||
StringState = Literal['orig', 'unescaped', 'ascii', 'empty']
|
||||
CONTAINER_STATES: list[ContainerState] = ['orig', 'array', 'flat']
|
||||
SCALAR_STATES: list[ScalarState] = ['orig', '1digit', 'str']
|
||||
STRING_STATES: list[StringState] = ['orig', 'unescaped', 'ascii', 'empty']
|
||||
|
||||
def right_pad(padded_length: int, b: bytes):
|
||||
assert len(b) <= padded_length
|
||||
return b + b' '*(padded_length-len(b))
|
||||
|
||||
def right_pad2(r: bytes, b: bytes):
|
||||
print(f"right_pad({r}, {b})")
|
||||
return right_pad(len(r), b)
|
||||
|
||||
class JsonFile:
|
||||
def __init__(self,
|
||||
original_json_file: Path,
|
||||
container_state: ContainerState = 'orig',
|
||||
scalar_state: ScalarState = 'orig',
|
||||
string_state: StringState = 'orig'):
|
||||
self.original_json_file = original_json_file
|
||||
self.container_state: ContainerState = container_state
|
||||
self.scalar_state: ScalarState = scalar_state
|
||||
self.string_state: StringState = string_state
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
if self.container_state == 'orig' and self.scalar_state == 'orig' and self.string_state == 'orig':
|
||||
return self.original_json_file
|
||||
else:
|
||||
return self.original_json_file.with_stem(f"{self.original_json_file.stem}-{self.container_state}-{self.scalar_state}-{self.string_state}")
|
||||
|
||||
def write(self, force: bool = False):
|
||||
if force or not self.path.exists():
|
||||
with open(self.path, 'wb') as out:
|
||||
self.write_to(out)
|
||||
|
||||
def with_container_state(self, container_state: ContainerState):
|
||||
return JsonFile(self.original_json_file, container_state, self.scalar_state, self.string_state)
|
||||
def with_scalar_state(self, scalar_state: ScalarState):
|
||||
return JsonFile(self.original_json_file, self.container_state, scalar_state, self.string_state)
|
||||
def with_string_state(self, string_state: StringState):
|
||||
return JsonFile(self.original_json_file, self.container_state, self.scalar_state, string_state)
|
||||
|
||||
def open(self):
|
||||
return open(self.path, 'rb')
|
||||
|
||||
def write_to(self, out: BufferedWriter):
|
||||
if self.string_state == 'unescaped':
|
||||
return self.remove_escapes(self.with_string_state('orig').open(), out)
|
||||
elif self.string_state == 'ascii':
|
||||
return self.remove_utf8(self.with_string_state('unescaped').open(), out)
|
||||
elif self.string_state == 'empty':
|
||||
return self.replace_strings(self.with_string_state('ascii').open(), out, b'""')
|
||||
else:
|
||||
assert self.string_state == 'orig'
|
||||
|
||||
if self.scalar_state == '1digit':
|
||||
return self.replace_numbers(self.with_scalar_state('orig').open(), out, b'0')
|
||||
elif self.scalar_state == 'str':
|
||||
return self.replace_non_strings(self.with_scalar_state('1digit').open(), out, b'""')
|
||||
else:
|
||||
assert self.scalar_state == 'orig'
|
||||
|
||||
if self.container_state == 'array':
|
||||
return self.replace_objects_with_arrays(self.with_container_state('orig').open(), out)
|
||||
elif self.container_state == 'flat':
|
||||
return self.remove_nesting(self.with_container_state('array').open(), out)
|
||||
else:
|
||||
assert self.container_state == 'orig'
|
||||
|
||||
assert self.path.exists()
|
||||
|
||||
def remove_escapes(self, input: BufferedReader, out: BufferedWriter):
|
||||
for line in input:
|
||||
out.write(re.sub(rb'\\(.)', rb'__', line))
|
||||
|
||||
def remove_utf8(self, input: BufferedReader, out: BufferedWriter):
|
||||
for line in input:
|
||||
out.write(bytes([(b if b < 128 else ord('_')) for b in line]))
|
||||
|
||||
def replace_strings(self, input: BufferedReader, out: BufferedWriter, replacement: bytes):
|
||||
for line in input:
|
||||
assert line.find(b'\\') == -1
|
||||
out.write(re.sub(rb'"([^"]*)"', lambda s: right_pad(len(s.group(0)), replacement), line))
|
||||
|
||||
def replace_numbers(self, input: BufferedReader, out: BufferedWriter, replacement: bytes):
|
||||
for line in input:
|
||||
for (non_string, string) in self.split_by_strings(line):
|
||||
out.write(re.sub(rb'\s*[-0-9][-+0-9.eE]*\s*', lambda s: right_pad(len(s.group(0)), replacement), non_string))
|
||||
out.write(string)
|
||||
|
||||
def replace_non_strings(self, input: BufferedReader, out: BufferedWriter, replacement: bytes):
|
||||
for line in input:
|
||||
for (non_string, string) in self.split_by_strings(line):
|
||||
out.write(re.sub(rb'\s*[^,:{}[\] \r\t\n]+\s*', lambda s: right_pad(len(s.group(0)), replacement), non_string))
|
||||
out.write(string)
|
||||
|
||||
def replace_objects_with_arrays(self, input: BufferedReader, out: BufferedWriter):
|
||||
for line in input:
|
||||
for (non_string, string) in self.split_by_strings(line):
|
||||
out.write(non_string.replace(b'{', b'[').replace(b'}', b']').replace(b':', b','))
|
||||
out.write(string)
|
||||
|
||||
def remove_nesting(self, input: BufferedReader, out: BufferedWriter):
|
||||
prev_line = None
|
||||
is_first_line = True
|
||||
lines = iter(input)
|
||||
line = next(lines, None)
|
||||
next_line = None
|
||||
while line is not None:
|
||||
out_line = b''
|
||||
# Remove any { } or [ ], and replace : with ,
|
||||
for (non_string, string) in self.split_by_strings(line):
|
||||
# Replace empty objects or arrays with ""
|
||||
non_string = re.sub(rb'(\{(\s|\n)*\}|\[(\s|\n*)\])', lambda s: right_pad(len(s.group(0)), b'""'), non_string)
|
||||
# Remove other braces entirely
|
||||
non_string = re.sub(rb'([{}[\]])', lambda s: right_pad(len(s.group(0)), b' '), non_string)
|
||||
# Replace : with ,
|
||||
non_string = non_string.replace(b':', b',')
|
||||
out_line += non_string
|
||||
out_line += string
|
||||
|
||||
# Replace the first character with [
|
||||
if next_line is None:
|
||||
assert line[0] in [ord(x) for x in [ b'[', b'{', b' ', b'\t', b'\r', b'\n' ]]
|
||||
out_line = b'[' + out_line[1:]
|
||||
|
||||
# Replace the last character with ]
|
||||
next_line = next(lines, None)
|
||||
if next_line is None:
|
||||
assert out_line[-1] in [ord(x) for x in [ b']', b'}', b' ', b'\t', b'\r', b'\n' ]]
|
||||
out_line = bytes(out_line[:-1] + b']')
|
||||
line = next_line
|
||||
out.write(out_line)
|
||||
|
||||
def split_by_strings(self, line: bytes):
|
||||
result: list[tuple[bytes, bytes]] = []
|
||||
while len(line) > 0:
|
||||
quote = line.find(b'"')
|
||||
if quote == -1:
|
||||
result.append((line, b''))
|
||||
break
|
||||
end_quote = quote+1
|
||||
while line[end_quote] != ord(b'"'):
|
||||
assert end_quote < len(line)
|
||||
if line[end_quote] == ord(b'\\'):
|
||||
end_quote += 1
|
||||
end_quote += 1
|
||||
result.append((line[:quote],line[quote:end_quote+1]))
|
||||
line = line[end_quote+1:]
|
||||
return result
|
||||
|
||||
original_json_file = Path(sys.argv[1])
|
||||
for container_state in CONTAINER_STATES:
|
||||
for scalar_state in SCALAR_STATES:
|
||||
for string_state in STRING_STATES:
|
||||
output_file = JsonFile(original_json_file, container_state, scalar_state, string_state)
|
||||
if output_file.path.exists():
|
||||
print(f"Skipping {output_file.path}")
|
||||
continue
|
||||
print(f"Writing {output_file.path}")
|
||||
output_file.write()
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+509
-412
File diff suppressed because it is too large
Load Diff
+104
-1031
File diff suppressed because it is too large
Load Diff
@@ -66,16 +66,6 @@ namespace number_tests {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bomskip() {
|
||||
TEST_START();
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::padded_string docdata = "\xEF\xBB\xBF{\"score\":0.8825149536132812}"_padded;
|
||||
double score;
|
||||
ASSERT_SUCCESS(parser.parse(docdata)["score"].get_double().get(score));
|
||||
ASSERT_EQUAL(score, 0.8825149536132812);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool issue2017() {
|
||||
TEST_START();
|
||||
simdjson::dom::parser parser;
|
||||
@@ -396,8 +386,7 @@ namespace number_tests {
|
||||
}
|
||||
|
||||
bool run() {
|
||||
return bomskip() &&
|
||||
issue2017() &&
|
||||
return issue2017() &&
|
||||
truncated_borderline() &&
|
||||
specific_tests() &&
|
||||
ground_truth() &&
|
||||
@@ -1669,7 +1658,6 @@ namespace validate_tests {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_validate() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
const std::string test = R"({ "foo" : 1, "bar" : [ 1, 2, 3 ], "baz": { "a": 1, "b": 2, "c": 3 } })";
|
||||
@@ -1678,7 +1666,6 @@ namespace validate_tests {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_range() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
for(size_t len = 0; len <= 128; len++) {
|
||||
@@ -1696,7 +1683,6 @@ namespace validate_tests {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_issue1169() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
std::vector<uint8_t> source(64,' ');
|
||||
@@ -1707,7 +1693,6 @@ namespace validate_tests {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_issue1169_long() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
for(size_t len = 1; len <= 128; len++) {
|
||||
@@ -1717,7 +1702,6 @@ namespace validate_tests {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_random() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
std::vector<uint8_t> source(64,' ');
|
||||
@@ -1779,7 +1763,6 @@ namespace minify_tests {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// this is meant to test buffer overflows.
|
||||
bool test_various_lengths2() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
@@ -1798,7 +1781,6 @@ namespace minify_tests {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_single_quote() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
const std::string test = "\"";
|
||||
@@ -1819,14 +1801,12 @@ namespace minify_tests {
|
||||
const std::string minified(R"({"foo":1,"bar":[1,2,0.11111111111111113],"baz":{"a":3.1415926535897936,"b":2,"c":3.141592653589794}})");
|
||||
return check_minification(test.c_str(), test.size(), minified.c_str(), minified.size());
|
||||
}
|
||||
|
||||
bool test_minify_array() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
std::string test("[ 1, 2, 3]");
|
||||
std::string minified("[1,2,3]");
|
||||
return check_minification(test.c_str(), test.size(), minified.c_str(), minified.size());
|
||||
}
|
||||
|
||||
bool test_minify_object() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
std::string test(R"({ "foo " : 1, "b ar" : [ 1, 2, 3 ], "baz": { "a": 1, "b": 2, "c": 3 } })");
|
||||
@@ -1869,7 +1849,6 @@ namespace format_tests {
|
||||
s << doc;
|
||||
return assert_minified(s);
|
||||
}
|
||||
|
||||
bool print_minify_parser_parse() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
@@ -1889,7 +1868,6 @@ namespace format_tests {
|
||||
s << value;
|
||||
return assert_minified(s, "1");
|
||||
}
|
||||
|
||||
bool print_minify_element() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
@@ -1909,7 +1887,6 @@ namespace format_tests {
|
||||
s << array;
|
||||
return assert_minified(s, "[1,2,0.11111111111111113]");
|
||||
}
|
||||
|
||||
bool print_minify_array() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
@@ -1929,7 +1906,6 @@ namespace format_tests {
|
||||
s << object;
|
||||
return assert_minified(s, R"({"a":3.1415926535897936,"b":2,"c":3.141592653589794})");
|
||||
}
|
||||
|
||||
bool print_minify_object() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
@@ -1949,7 +1925,6 @@ namespace format_tests {
|
||||
s << parser.parse(DOCUMENT);
|
||||
return assert_minified(s);
|
||||
}
|
||||
|
||||
bool print_minify_parser_parse_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
@@ -1965,7 +1940,6 @@ namespace format_tests {
|
||||
s << parser.parse(DOCUMENT)["foo"];
|
||||
return assert_minified(s, "1");
|
||||
}
|
||||
|
||||
bool print_minify_element_result_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
@@ -1982,7 +1956,6 @@ namespace format_tests {
|
||||
s << value;
|
||||
return assert_minified(s, "1");
|
||||
}
|
||||
|
||||
bool print_minify_element_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
@@ -1999,7 +1972,6 @@ namespace format_tests {
|
||||
s << parser.parse(DOCUMENT)["bar"].get_array();
|
||||
return assert_minified(s, "[1,2,0.11111111111111113]");
|
||||
}
|
||||
|
||||
bool print_minify_array_result_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
|
||||
@@ -397,33 +397,6 @@ namespace document_stream_tests {
|
||||
std::cout << "number of documents " << count << std::endl;
|
||||
return count == 1;
|
||||
}
|
||||
|
||||
bool skipbom() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
simdjson::dom::parser parser;
|
||||
auto json = "\xEF\xBB\xBF{\"hello\": \"world\"}"_padded;
|
||||
simdjson::dom::document_stream stream;
|
||||
ASSERT_SUCCESS(parser.parse_many(json).get(stream));
|
||||
size_t count = 0;
|
||||
for (auto doc : stream) {
|
||||
if(doc.error()) {
|
||||
std::cerr << "Unexpected error: " << doc.error() << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::string expected = R"({"hello":"world"})";
|
||||
simdjson::dom::element this_document;
|
||||
ASSERT_SUCCESS(doc.get(this_document));
|
||||
|
||||
std::string answer = simdjson::minify(this_document);
|
||||
if(answer != expected) {
|
||||
std::cout << this_document << std::endl;
|
||||
return false;
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
std::cout << "number of documents " << count << std::endl;
|
||||
return count == 1;
|
||||
}
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
bool single_document_exceptions() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
@@ -940,8 +913,7 @@ namespace document_stream_tests {
|
||||
}
|
||||
|
||||
bool run() {
|
||||
return skipbom() &&
|
||||
fuzzaccess() &&
|
||||
return fuzzaccess() &&
|
||||
baby_fuzzer() &&
|
||||
issue1649() &&
|
||||
adversarial_single_document_array() &&
|
||||
|
||||
@@ -51,10 +51,6 @@ namespace document_tests {
|
||||
simdjson::dom::array array;
|
||||
ASSERT_SUCCESS( parser.parse(smalljson).get(array) );
|
||||
ASSERT_EQUAL( array.size(), 3 );
|
||||
ASSERT_EQUAL( *array.begin() < *array.end(), true );
|
||||
ASSERT_EQUAL( *array.end() < *array.begin(), false );
|
||||
ASSERT_EQUAL( *array.begin() == *array.begin(), true );
|
||||
ASSERT_EQUAL( *array.begin() == *array.end(), false );
|
||||
return true;
|
||||
}
|
||||
bool count_object_example() {
|
||||
@@ -64,10 +60,6 @@ namespace document_tests {
|
||||
simdjson::dom::object object;
|
||||
ASSERT_SUCCESS( parser.parse(smalljson).get(object) );
|
||||
ASSERT_EQUAL( object.size(), 3 );
|
||||
ASSERT_EQUAL( (*object.begin()).value < (*object.end()).value, true );
|
||||
ASSERT_EQUAL( (*object.end()).value < (*object.begin()).value, false );
|
||||
ASSERT_EQUAL( (*object.begin()).value == (*object.begin()).value, true );
|
||||
ASSERT_EQUAL( (*object.begin()).value == (*object.end()).value, false );
|
||||
return true;
|
||||
}
|
||||
bool padded_with_open_bracket() {
|
||||
@@ -240,4 +232,4 @@ int main(int argc, char *argv[]) {
|
||||
} else {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ add_cpp_test(ondemand_ordering_tests LABELS ondemand acceptance per_impl
|
||||
add_cpp_test(ondemand_parse_api_tests LABELS ondemand acceptance per_implementation)
|
||||
add_cpp_test(ondemand_readme_examples LABELS ondemand acceptance per_implementation)
|
||||
add_cpp_test(ondemand_scalar_tests LABELS ondemand acceptance per_implementation)
|
||||
add_cpp_test(ondemand_to_string LABELS ondemand acceptance per_implementation)
|
||||
add_cpp_test(ondemand_twitter_tests LABELS ondemand acceptance per_implementation)
|
||||
add_cpp_test(ondemand_wrong_type_error_tests LABELS ondemand acceptance per_implementation)
|
||||
add_cpp_test(ondemand_iterate_many_csv LABELS ondemand acceptance per_implementation)
|
||||
|
||||
@@ -322,43 +322,6 @@ namespace document_stream_tests {
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool skipbom() {
|
||||
TEST_START();
|
||||
auto json = "\xEF\xBB\xBF[1,[1,2]] {\"a\":1,\"b\":2} {\"o\":{\"1\":1,\"2\":2}} [1,2,3]"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document_stream stream;
|
||||
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
|
||||
std::string_view expected[4] = {"[1,[1,2]]", "{\"a\":1,\"b\":2}", "{\"o\":{\"1\":1,\"2\":2}}", "[1,2,3]"};
|
||||
size_t counter{0};
|
||||
auto i = stream.begin();
|
||||
int64_t x;
|
||||
|
||||
ASSERT_EQUAL(i.source(),expected[counter++]);
|
||||
ASSERT_SUCCESS( (*i).at_pointer("/1/1").get(x) );
|
||||
ASSERT_EQUAL(x,2);
|
||||
++i;
|
||||
|
||||
ASSERT_EQUAL(i.source(),expected[counter++]);
|
||||
simdjson_result<ondemand::document_reference> xxx = *i;
|
||||
ASSERT_SUCCESS( xxx.find_field("a").get(x) );
|
||||
ASSERT_EQUAL(x,1);
|
||||
++i;
|
||||
|
||||
ASSERT_EQUAL(i.source(),expected[counter++]);
|
||||
ASSERT_SUCCESS( (*i).at_pointer("/o/2").get(x) );
|
||||
ASSERT_EQUAL(x,2);
|
||||
++i;
|
||||
|
||||
ASSERT_EQUAL(i.source(),expected[counter++]);
|
||||
ASSERT_SUCCESS( (*i).at_pointer("/2").get(x) );
|
||||
ASSERT_EQUAL(x,3);
|
||||
++i;
|
||||
|
||||
if (i != stream.end()) { return false; }
|
||||
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool atoms_json() {
|
||||
TEST_START();
|
||||
auto json = R"(5 true 20.3 "string" )"_padded;
|
||||
@@ -840,7 +803,6 @@ namespace document_stream_tests {
|
||||
|
||||
bool run() {
|
||||
return
|
||||
skipbom() &&
|
||||
issue1977() &&
|
||||
string_with_trailing() &&
|
||||
uint64_with_trailing() &&
|
||||
|
||||
@@ -16,18 +16,6 @@ namespace misc_tests {
|
||||
ASSERT_FALSE(b);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
bool skipbom() {
|
||||
auto error_phrase = "\xEF\xBB\xBF false"_padded;
|
||||
TEST_START();
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc;
|
||||
ASSERT_SUCCESS(parser.iterate(error_phrase).get(doc));
|
||||
bool b;
|
||||
ASSERT_SUCCESS( doc.get_bool().get(b));
|
||||
ASSERT_FALSE(b);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
bool issue1981_failure() {
|
||||
auto error_phrase = R"(falseA)"_padded;
|
||||
@@ -605,7 +593,6 @@ namespace misc_tests {
|
||||
|
||||
bool run() {
|
||||
return
|
||||
skipbom() &&
|
||||
issue1981_success() &&
|
||||
issue1981_failure() &&
|
||||
replacement_char() &&
|
||||
|
||||
@@ -144,20 +144,14 @@ namespace parse_api_tests {
|
||||
}
|
||||
|
||||
{
|
||||
std::string json = "12345642314123421321321321321321312321321321321312";
|
||||
std::string json = "12";
|
||||
json.shrink_to_fit();
|
||||
cout << "- string, 0 padding" << endl;
|
||||
ASSERT_SUCCESS( parser.iterate(json) );
|
||||
}
|
||||
|
||||
{
|
||||
std::string json = "12345642314123421321321321321321312321321321321312";
|
||||
json.shrink_to_fit();
|
||||
cout << "- string, 0 padding" << endl;
|
||||
ASSERT_ERROR( parser.iterate((const std::string&)json), INSUFFICIENT_PADDING );
|
||||
ASSERT_ERROR( parser.iterate(json), INSUFFICIENT_PADDING );
|
||||
// It's actually kind of hard to allocate "just enough" capacity, since the string tends
|
||||
// to grow more than you tell it to.
|
||||
}
|
||||
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "simdjson.h"
|
||||
#include "test_ondemand.h"
|
||||
#if __cpp_lib_optional >= 201606L
|
||||
#include <optional>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace simdjson;
|
||||
using error_code=simdjson::error_code;
|
||||
@@ -22,39 +20,7 @@ bool string2() {
|
||||
}
|
||||
|
||||
|
||||
bool to_string_example_no_except() {
|
||||
TEST_START();
|
||||
auto json = R"({
|
||||
"name": "Daniel",
|
||||
"age": 42
|
||||
})"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc;
|
||||
auto err = parser.iterate(json).get(doc);
|
||||
if(err) { return false; }
|
||||
std::string name;
|
||||
err = doc["name"].get_string(name);
|
||||
if(err) { return false; }
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
|
||||
bool to_string_example() {
|
||||
TEST_START();
|
||||
auto json = R"({
|
||||
"name": "Daniel",
|
||||
"age": 42
|
||||
})"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc = parser.iterate(json);
|
||||
std::string name;
|
||||
doc["name"].get_string(name);
|
||||
ASSERT_EQUAL(name, "Daniel");
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool gen_raw1() {
|
||||
TEST_START();
|
||||
simdjson::ondemand::parser parser;
|
||||
@@ -107,144 +73,6 @@ bool at_end() {
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool examplecrt() {
|
||||
TEST_START();
|
||||
padded_string padded_input_json = R"([
|
||||
{ "monitor": [
|
||||
{ "id": "monitor", "type": "toggle", "label": "monitor" },
|
||||
{ "id": "profile", "type": "selector", "label": "collection" },
|
||||
{ "id": "overlay", "type": "selector", "label": "overlay" },
|
||||
{ "id": "zoom", "type": "toggleSlider", "label": "zoom" }
|
||||
] },
|
||||
|
||||
{ "crt": [
|
||||
{ "id": "system", "type": "multi", "label": "system", "choices": "PAL, NTSC" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "brightness", "type": "slider", "icon": "brightness" },
|
||||
{ "id": "contrast", "type": "slider", "icon": "contrast" },
|
||||
{ "id": "saturation", "type": "slider", "icon": "saturation" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "overscan", "type": "toggleSlider", "label": "overscan" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "emulation", "type": "toggle", "label": "CRT emulation" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "curve", "type": "toggleSlider", "label": "curve" },
|
||||
{ "id": "bleed", "type": "toggleSlider", "label": "bleed" },
|
||||
{ "id": "vignette", "type": "toggleSlider", "label": "vignette" },
|
||||
{ "id": "scanlines", "type": "toggleSlider", "label": "scanlines" },
|
||||
{ "id": "gridlines", "type": "toggleSlider", "label": "gridlines" },
|
||||
{ "id": "glow", "type": "toggleSlider", "label": "glow" },
|
||||
{ "id": "flicker", "type": "toggleSlider", "label": "flicker" },
|
||||
{ "id": "noise", "type": "toggleSlider", "label": "noise" },
|
||||
{}
|
||||
] }
|
||||
])"_padded;
|
||||
auto parser = ondemand::parser{};
|
||||
auto doc = parser.iterate(padded_input_json);
|
||||
auto root_array = doc.get_array();
|
||||
// the root should be an object, not an array, but that's the JSON we are
|
||||
// given.
|
||||
for (ondemand::object node : root_array) {
|
||||
// We know that we are going to have just one element in the object.
|
||||
for (auto field : node) {
|
||||
std::cout << "\n\ntop level:" << field.key() << std::endl;
|
||||
// You can get a proper std::string_view for the key with:
|
||||
// std::string_view key = field.unescaped_key();
|
||||
// and second for-range loop to get child-elements here
|
||||
for (ondemand::object inner_object : field.value()) {
|
||||
auto i = inner_object.begin();
|
||||
if (i == inner_object.end()) {
|
||||
std::cout << "empty object" << std::endl;
|
||||
continue;
|
||||
} else {
|
||||
for (; i != inner_object.end(); ++i) {
|
||||
auto inner_field = *i;
|
||||
std::cout << '"' << inner_field.key()
|
||||
<< "\" : " << inner_field.value() << ", ";
|
||||
// You can get proper std::string_view for the key and value with:
|
||||
// std::string_view inner_key = field.unescaped_key();
|
||||
// std::string_view value_str = field.value();
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
// You can break here if you only want just the first element.
|
||||
// break;
|
||||
}
|
||||
}
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
bool examplecrt_realloc() {
|
||||
TEST_START();
|
||||
std::string unpadded_input_json = R"([
|
||||
{ "monitor": [
|
||||
{ "id": "monitor", "type": "toggle", "label": "monitor" },
|
||||
{ "id": "profile", "type": "selector", "label": "collection" },
|
||||
{ "id": "overlay", "type": "selector", "label": "overlay" },
|
||||
{ "id": "zoom", "type": "toggleSlider", "label": "zoom" }
|
||||
] },
|
||||
|
||||
{ "crt": [
|
||||
{ "id": "system", "type": "multi", "label": "system", "choices": "PAL, NTSC" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "brightness", "type": "slider", "icon": "brightness" },
|
||||
{ "id": "contrast", "type": "slider", "icon": "contrast" },
|
||||
{ "id": "saturation", "type": "slider", "icon": "saturation" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "overscan", "type": "toggleSlider", "label": "overscan" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "emulation", "type": "toggle", "label": "CRT emulation" },
|
||||
{ "type": "spacer" },
|
||||
{ "id": "curve", "type": "toggleSlider", "label": "curve" },
|
||||
{ "id": "bleed", "type": "toggleSlider", "label": "bleed" },
|
||||
{ "id": "vignette", "type": "toggleSlider", "label": "vignette" },
|
||||
{ "id": "scanlines", "type": "toggleSlider", "label": "scanlines" },
|
||||
{ "id": "gridlines", "type": "toggleSlider", "label": "gridlines" },
|
||||
{ "id": "glow", "type": "toggleSlider", "label": "glow" },
|
||||
{ "id": "flicker", "type": "toggleSlider", "label": "flicker" },
|
||||
{ "id": "noise", "type": "toggleSlider", "label": "noise" },
|
||||
{}
|
||||
] }
|
||||
])";
|
||||
unpadded_input_json.shrink_to_fit();
|
||||
auto parser = ondemand::parser{};
|
||||
auto doc = parser.iterate(unpadded_input_json);
|
||||
auto root_array = doc.get_array();
|
||||
// the root should be an object, not an array, but that's the JSON we are
|
||||
// given.
|
||||
for (ondemand::object node : root_array) {
|
||||
// We know that we are going to have just one element in the object.
|
||||
for (auto field : node) {
|
||||
std::cout << "\n\ntop level:" << field.key() << std::endl;
|
||||
// You can get a proper std::string_view for the key with:
|
||||
// std::string_view key = field.unescaped_key();
|
||||
// and second for-range loop to get child-elements here
|
||||
for (ondemand::object inner_object : field.value()) {
|
||||
auto i = inner_object.begin();
|
||||
if (i == inner_object.end()) {
|
||||
std::cout << "empty object" << std::endl;
|
||||
continue;
|
||||
} else {
|
||||
for (; i != inner_object.end(); ++i) {
|
||||
auto inner_field = *i;
|
||||
std::cout << '"' << inner_field.key()
|
||||
<< "\" : " << inner_field.value() << ", ";
|
||||
// You can get proper std::string_view for the key and value with:
|
||||
// std::string_view inner_key = field.unescaped_key();
|
||||
// std::string_view value_str = field.value();
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
// You can break here if you only want just the first element.
|
||||
// break;
|
||||
}
|
||||
}
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool number_tests() {
|
||||
TEST_START();
|
||||
ondemand::parser parser;
|
||||
@@ -1481,60 +1309,10 @@ bool example1958() {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool to_optional() {
|
||||
TEST_START();
|
||||
auto json = R"({ "foo1": "3.1416" } )"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc = parser.iterate(json);
|
||||
#if __cpp_lib_optional >= 201606L
|
||||
std::optional<std::string> value;
|
||||
ASSERT_SUCCESS(doc["foo1"].get_string(value));
|
||||
std::cout << value.value() << std::endl;
|
||||
#else
|
||||
std::string value;
|
||||
ASSERT_SUCCESS(doc["foo1"].get_string(value));
|
||||
std::cout << value << std::endl;
|
||||
#endif
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool value_raw_json_array() {
|
||||
TEST_START();
|
||||
auto json = R"( [1,2,"fds", {"a":1}, [1,344]] )"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc = parser.iterate(json);
|
||||
std::string_view expected[] = {"1", "2", "\"fds\"", "{\"a\":1}", "[1,344]"};
|
||||
size_t counter = 0;
|
||||
for(auto array: doc) {
|
||||
std::string_view raw = array.raw_json();
|
||||
ASSERT_EQUAL(raw, expected[counter++]);
|
||||
}
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
bool value_raw_json_object() {
|
||||
TEST_START();
|
||||
auto json = R"( {"key1":1,"key2":2,"key3":"fds", "key4":{"a":1}, "key5":[1,344]} )"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc = parser.iterate(json);
|
||||
std::string_view expected[] = {"1", "2", "\"fds\"", "{\"a\":1}", "[1,344]"};
|
||||
size_t counter = 0;
|
||||
for(auto key_value: doc.get_object()) {
|
||||
std::string_view raw = key_value.value().raw_json();
|
||||
ASSERT_EQUAL(raw, expected[counter++]);
|
||||
}
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
#endif
|
||||
bool run() {
|
||||
return true
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
&& to_optional()
|
||||
&& value_raw_json_array() && value_raw_json_object()
|
||||
&& gen_raw1() && gen_raw2() && gen_raw3()
|
||||
&& at_end()
|
||||
&& example1956() && example1958()
|
||||
@@ -1574,14 +1352,10 @@ bool run() {
|
||||
&& current_location_user_error()
|
||||
&& current_location_out_of_bounds()
|
||||
&& current_location_no_error()
|
||||
&& to_string_example_no_except()
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
&& to_string_example()
|
||||
&& raw_string()
|
||||
&& number_tests()
|
||||
&& current_location_tape_error_with_except()
|
||||
&& examplecrt()
|
||||
&& examplecrt_realloc()
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
#include "simdjson.h"
|
||||
#include "test_ondemand.h"
|
||||
|
||||
using namespace simdjson;
|
||||
|
||||
namespace json_package_tests {
|
||||
using namespace std;
|
||||
bool baby() {
|
||||
TEST_START();
|
||||
auto json = R"({
|
||||
"name": "Daniel",
|
||||
"age": 42
|
||||
})"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc;
|
||||
ASSERT_SUCCESS(parser.iterate(json).get(doc));
|
||||
|
||||
simdjson::ondemand::object main_object;
|
||||
ASSERT_SUCCESS(doc.get_object().get(main_object));
|
||||
std::string name;
|
||||
ASSERT_SUCCESS(main_object["name"].get_string(name));
|
||||
ASSERT_EQUAL(name, "Daniel");
|
||||
uint64_t age;
|
||||
ASSERT_SUCCESS(main_object["age"].get_uint64().get(age));
|
||||
ASSERT_EQUAL(age, 42);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool thirtysecondsofcode() {
|
||||
TEST_START();
|
||||
auto json = R"({
|
||||
"name": "30-seconds-of-code",
|
||||
"private": true,
|
||||
"version": "10.0.0",
|
||||
"description": "30 seconds of code website.",
|
||||
"exports": "./index.js",
|
||||
"author": "chalarangelo",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@jsiqle/core": "^3.0.0",
|
||||
"astro": "^3.2.0",
|
||||
"chalk": "^5.3.0",
|
||||
"eslint": "^8.50.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"front-matter": "^4.0.2",
|
||||
"fs-extra": "^11.1.1",
|
||||
"glob": "^10.3.10",
|
||||
"hast-util-to-html": "^9.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"mdast-util-to-hast": "^13.0.2",
|
||||
"prettier": "^3.0.3",
|
||||
"prettier-plugin-astro": "^0.12.0",
|
||||
"prismjs": "^1.29.0",
|
||||
"remark": "^15.0.1",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"sass": "^1.68.0",
|
||||
"sharp": "^0.32.6",
|
||||
"unist-util-select": "^5.0.0",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"unist-util-visit-parents": "^6.0.1",
|
||||
"webfonts-generator": "^0.4.0"
|
||||
},
|
||||
"imports": {
|
||||
"#blocks/*": "./src/blocks/*.js",
|
||||
"#components/*": "./src/components/*.astro",
|
||||
"#layouts/*": "./src/layouts/*.astro",
|
||||
"#settings/*": "./src/settings/*.js",
|
||||
"#prefabs": "./src/prefabs/index.js",
|
||||
"#utils": "./src/utils/index.js",
|
||||
"#utils/search": "./src/utils/search.js"
|
||||
},
|
||||
"scripts": {
|
||||
"predev": "NODE_ENV=development node ./src/scripts/develop.js",
|
||||
"dev": "astro dev --port 8000",
|
||||
"start": "astro dev --port 8000",
|
||||
"prebuild": "NODE_ENV=production node ./src/scripts/build.js",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview --port 9000",
|
||||
"watch": "NODE_ENV=development node ./src/scripts/watch.js",
|
||||
"console": "NODE_ENV=production node ./src/scripts/console.js",
|
||||
"create": "NODE_ENV=production node ./src/scripts/create.js",
|
||||
"icons": "NODE_ENV=production node ./src/scripts/icons.js",
|
||||
"manifest": "NODE_ENV=production node ./src/scripts/manifest.js"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/30-seconds/30-seconds-of-code"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/30-seconds/30-seconds-of-code/issues"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 0.5% and last 4 versions and not dead and not ie>0 and not op_mini all and not and_uc>0 and not edge<79"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18.14.2"
|
||||
}
|
||||
})"_padded;
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc;
|
||||
ASSERT_SUCCESS(parser.iterate(json).get(doc));
|
||||
|
||||
simdjson::ondemand::object main_object;
|
||||
ASSERT_SUCCESS(doc.get_object().get(main_object));
|
||||
|
||||
simdjson::ondemand::raw_json_string key;
|
||||
simdjson::ondemand::value value;
|
||||
|
||||
for (auto field : main_object) {
|
||||
// Throw error if getting key or value fails.
|
||||
ASSERT_SUCCESS(field.key().get(key));
|
||||
ASSERT_SUCCESS(field.value().get(value));
|
||||
|
||||
if (key == "name") {
|
||||
std::string name;
|
||||
ASSERT_SUCCESS(value.get_string(name));
|
||||
ASSERT_EQUAL(name, "30-seconds-of-code");
|
||||
} else if (key == "main") {
|
||||
std::string main;
|
||||
ASSERT_SUCCESS(value.get_string(main));
|
||||
// unused
|
||||
} else if (key == "exports") {
|
||||
simdjson::ondemand::json_type exports_type;
|
||||
if (!value.type().get(exports_type)) {
|
||||
std::string_view exports;
|
||||
switch (exports_type) {
|
||||
case simdjson::ondemand::json_type::object: {
|
||||
simdjson::ondemand::object exports_object;
|
||||
if (!value.get_object().get(exports_object) &&
|
||||
!exports_object.raw_json().get(exports)) {
|
||||
// unused
|
||||
}
|
||||
break;
|
||||
}
|
||||
case simdjson::ondemand::json_type::array: {
|
||||
simdjson::ondemand::array exports_array;
|
||||
if (!value.get_array().get(exports_array) &&
|
||||
!exports_array.raw_json().get(exports)) {
|
||||
// unused
|
||||
}
|
||||
break;
|
||||
}
|
||||
case simdjson::ondemand::json_type::string: {
|
||||
if (!value.get_string().get(exports)) {
|
||||
ASSERT_EQUAL(exports, "./index.js");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (key == "imports") {
|
||||
simdjson::ondemand::json_type imports_type;
|
||||
if (!value.type().get(imports_type)) {
|
||||
std::string_view imports;
|
||||
switch (imports_type) {
|
||||
case simdjson::ondemand::json_type::object: {
|
||||
simdjson::ondemand::object imports_object;
|
||||
if (!value.get_object().get(imports_object) &&
|
||||
!imports_object.raw_json().get(imports)) {
|
||||
ASSERT_EQUAL(imports, R"({
|
||||
"#blocks/*": "./src/blocks/*.js",
|
||||
"#components/*": "./src/components/*.astro",
|
||||
"#layouts/*": "./src/layouts/*.astro",
|
||||
"#settings/*": "./src/settings/*.js",
|
||||
"#prefabs": "./src/prefabs/index.js",
|
||||
"#utils": "./src/utils/index.js",
|
||||
"#utils/search": "./src/utils/search.js"
|
||||
})");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case simdjson::ondemand::json_type::array: {
|
||||
simdjson::ondemand::array imports_array;
|
||||
if (!value.get_array().get(imports_array) &&
|
||||
!imports_array.raw_json().get(imports)) {
|
||||
// unused
|
||||
}
|
||||
break;
|
||||
}
|
||||
case simdjson::ondemand::json_type::string: {
|
||||
if (!value.get_string().get(imports)) {
|
||||
// unused
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (key == "type") {
|
||||
std::string_view type;
|
||||
if (!value.get_string().get(type) &&
|
||||
(type == "commonjs" || type == "module")) {
|
||||
ASSERT_EQUAL(type, "module");
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool run() { return thirtysecondsofcode() && baby(); }
|
||||
|
||||
} // namespace json_package_tests
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
return test_main(argc, argv, json_package_tests::run);
|
||||
}
|
||||
@@ -167,6 +167,8 @@ print("the commandline is {}".format(cp.args))
|
||||
if(cp.returncode != 0):
|
||||
print("Failed to run doxygen")
|
||||
|
||||
#ipe = subprocess.Popen(["doxygen"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=maindir)
|
||||
#doxygenresult = pipe.communicate()[0].decode().strip()
|
||||
|
||||
pattern = re.compile("https://simdjson.org/api/(\d+\.\d+\.\d+)/index.html")
|
||||
readmefile = maindir + os.sep + "README.md"
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
# twitter.json Branch Miss Variants
|
||||
|
||||
| Contain | Scalars | Strings | Cycles | Instrs | Misses | Docs/sec |
|
||||
|---------|---------|-----------|--------:|---------:|-------:|---------:|
|
||||
| orig | orig | orig | 43.1557 | 140.4823 | 262 | 5051.3 |
|
||||
| orig | orig | unescaped | 40.9559 | 137.7313 | 210 | 5257.1 |
|
||||
| orig | orig | ascii | 40.8708 | 137.7313 | 219 | 5420.6 |
|
||||
| orig | orig | empty | 38.6624 | 134.2775 | 193 | 5634.1 |
|
||||
| orig | 1digit | orig | 41.5941 | 134.5389 | 299 | 5195.7 |
|
||||
| orig | 1digit | unescaped | 39.1917 | 131.7879 | 244 | 5422.2 |
|
||||
| orig | 1digit | ascii | 39.3877 | 131.7879 | 242 | 5560.8 |
|
||||
| orig | 1digit | empty | 37.1633 | 128.3341 | 204 | 5796.6 |
|
||||
| orig | str | orig | 46.2681 | 128.7201 | 193 | 4816.3 |
|
||||
| orig | str | unescaped | 43.7883 | 125.9691 | 186 | 5022.5 |
|
||||
| orig | str | ascii | 43.9507 | 125.9691 | 177 | 5147.6 |
|
||||
| orig | str | empty | 41.1975 | 122.5153 | 110 | 5397.7 |
|
||||
| array | orig | orig | 50.1138 | 171.0958 | 469 | 4548.1 |
|
||||
| array | orig | unescaped | 47.4255 | 168.3448 | 429 | 4738.2 |
|
||||
| array | orig | ascii | 47.5435 | 168.3448 | 426 | 4851.1 |
|
||||
| array | orig | empty | 45.5023 | 164.8910 | 406 | 5012.3 |
|
||||
| array | 1digit | orig | 47.5542 | 165.1527 | 386 | 4693.9 |
|
||||
| array | 1digit | unescaped | 45.8350 | 162.4017 | 342 | 4862.4 |
|
||||
| array | 1digit | ascii | 45.6465 | 162.4017 | 335 | 4995.8 |
|
||||
| array | 1digit | empty | 43.3332 | 158.9479 | 262 | 5205.8 |
|
||||
| array | str | orig | 52.0014 | 160.6582 | 331 | 4416.4 |
|
||||
| array | str | unescaped | 49.2261 | 157.9072 | 272 | 4618.3 |
|
||||
| array | str | ascii | 49.2947 | 157.9072 | 271 | 4728.9 |
|
||||
| array | str | empty | 46.3058 | 154.4534 | 179 | 4967.3 |
|
||||
| flat | orig | orig | 43.3339 | 159.8664 | 407 | 5049.4 |
|
||||
| flat | orig | unescaped | 41.7361 | 157.1154 | 384 | 5190.1 |
|
||||
| flat | orig | ascii | 41.6981 | 157.1154 | 393 | 5330.9 |
|
||||
| flat | orig | empty | 39.4102 | 153.6616 | 386 | 5583.5 |
|
||||
| flat | 1digit | orig | 41.7575 | 153.9234 | 364 | 5180.8 |
|
||||
| flat | 1digit | unescaped | 40.0306 | 151.1724 | 308 | 5344.4 |
|
||||
| flat | 1digit | ascii | 39.8567 | 151.1724 | 313 | 5507.9 |
|
||||
| flat | 1digit | empty | 37.3057 | 147.7186 | 250 | 5789.3 |
|
||||
| flat | str | orig | 46.2458 | 149.4289 | 471 | 4821.6 |
|
||||
| flat | str | unescaped | 44.4161 | 146.6778 | 413 | 4985.2 |
|
||||
| flat | str | ascii | 44.4534 | 146.6778 | 414 | 5112.6 |
|
||||
| flat | str | empty | 41.0894 | 143.2241 | 3 | 5419.1 |
|
||||
|
||||
## Container State Transition Miss Reduction
|
||||
|
||||
| Contain | orig orig | orig ascii | orig empty | 1digit orig | 1digit ascii | 1digit empty | str orig | str ascii | str empty |
|
||||
|---------------|----------:|-----------:|-----------:|------------:|-------------:|-------------:|---------:|----------:|----------:|
|
||||
| orig -> array | -207 | -207 | -213 | -87 | -93 | -58 | -138 | -94 | -69 |
|
||||
| orig -> flat | -145 | -174 | -193 | -65 | -71 | -46 | -278 | -237 | 107 |
|
||||
| array -> flat | 62 | 33 | 20 | 22 | 22 | 12 | -140 | -143 | 176 |
|
||||
|
||||
## Scalar State Transition Miss Reduction
|
||||
|
||||
| Scalars | orig orig | orig ascii | orig empty | array orig | array ascii | array empty | flat orig | flat ascii | flat empty |
|
||||
|----------------|----------:|-----------:|-----------:|-----------:|------------:|------------:|----------:|-----------:|-----------:|
|
||||
| orig -> 1digit | -37 | -23 | -11 | 83 | 91 | 144 | 43 | 80 | 136 |
|
||||
| orig -> str | 69 | 42 | 83 | 138 | 155 | 227 | -64 | -21 | 383 |
|
||||
| 1digit -> str | 106 | 65 | 94 | 55 | 64 | 83 | -107 | -101 | 247 |
|
||||
|
||||
## String State Transition Miss Reduction
|
||||
|
||||
| Strings | orig orig | orig 1digit | orig str | array orig | array 1digit | array str | flat orig | flat 1digit | flat str |
|
||||
|--------------------|----------:|------------:|---------:|-----------:|-------------:|----------:|----------:|------------:|---------:|
|
||||
| orig -> unescaped | 52 | 55 | 7 | 40 | 44 | 59 | 23 | 56 | 58 |
|
||||
| orig -> ascii | 43 | 57 | 16 | 43 | 51 | 60 | 14 | 51 | 57 |
|
||||
| orig -> empty | 69 | 95 | 83 | 63 | 124 | 152 | 21 | 114 | 468 |
|
||||
| unescaped -> ascii | -9 | 2 | 9 | 3 | 7 | 1 | -9 | -5 | -1 |
|
||||
| unescaped -> empty | 17 | 40 | 76 | 23 | 80 | 93 | -2 | 58 | 410 |
|
||||
| ascii -> empty | 26 | 38 | 67 | 20 | 73 | 92 | 7 | 63 | 411 |
|
||||
+535435
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user