Skip to content

Commit c56747b

Browse files
Merge pull request #28 from simdjson/adding_twitter_bench
Adding twitter bench
2 parents 7e57651 + 31803f0 commit c56747b

16 files changed

Lines changed: 16069 additions & 109 deletions

CMakeLists.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
cmake_minimum_required(VERSION 3.10)
22
set(CMAKE_C_COMPILER clang)
33
set(CMAKE_CXX_COMPILER clang++)
4-
4+
add_compile_options(-Wall -Wextra -freflection -stdlib=libc++ -std=c++26)
55
project(experimental_json_builder
66
VERSION 0.0.1
77
DESCRIPTION "Serializing gigabytes of JSON per second"
88
HOMEPAGE_URL "https://simdjson.org/"
99
LANGUAGES CXX
1010
)
11-
12-
set(CMAKE_CXX_STANDARD 23)
13-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
11+
if (NOT CMAKE_BUILD_TYPE)
12+
message(STATUS "No build type selected, default to Release")
13+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
14+
endif()
15+
#set(CMAKE_CXX_STANDARD 23)
16+
#set(CMAKE_CXX_STANDARD_REQUIRED ON)
1417

1518
include(cmake/CPM.cmake)
1619
# include simdjson
@@ -19,6 +22,7 @@ CPMAddPackage("gh:nlohmann/json@3.10.5")
1922

2023
# Optionally, specify the C++ compiler directly (here we use clang++)
2124
add_subdirectory(src)
25+
add_subdirectory(examples)
2226
add_subdirectory(benchmarks/src)
2327

2428
enable_testing()

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace ns {
3636
Or use one of the Macros described
3737
[here](https://github.com/nlohmann/json?tab=readme-ov-file#simplify-your-life-with-macros) in your class/struct.
3838

39-
By leveraging reflection, we can support for something as simple as:
39+
By leveraging compile-time reflection, we can support for something as simple as:
4040

4141
```c++
4242
int main() {
@@ -49,6 +49,10 @@ int main() {
4949

5050
With ~200 lines of code (as you can see in the [toy_builder.cpp](prototype_playground/toy_builder.cpp)).
5151

52+
As of now, we were able to implement this with ~1k lines of code (and that is including Neon + SSE2 optimizations in [json_escaping.hpp](src/json_escaping.hpp)).
53+
54+
The benchmark results show that our serialization speed can be 20/30x faster than [nlohmann](https://github.com/nlohmann/json).
55+
5256
## Current status
5357
There are 2 versions of compiler that aim to support the C++ 26 reflection paper.
5458

@@ -214,6 +218,11 @@ cmake --build build
214218
./build/benchmarks/src/SerializationBenchmark
215219
```
216220

221+
4. Run the (twitter) benchmark.
222+
```bash
223+
./build/benchmarks/src/SerializationTwitterBenchmark
224+
```
225+
217226
### Running tests
218227

219228
```bash

benchmarks/src/CMakeLists.txt

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,65 @@
1-
cmake_minimum_required(VERSION 3.10) # Set the minimum required version of CMake
1+
cmake_minimum_required(VERSION 3.10)
2+
3+
project(SerializatonTwitterBenchmark) # Name your project
24

3-
project(SerializationBenchmark) # Name your project
4-
if (NOT CMAKE_BUILD_TYPE)
5-
message(STATUS "No build type selected, default to Release")
6-
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
7-
endif()
85
# Set C++ standard to C++17 or higher if needed
9-
set(CMAKE_CXX_STANDARD 23)
10-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6+
#set(CMAKE_CXX_STANDARD 23)
7+
#set(CMAKE_CXX_STANDARD_REQUIRED ON)
118

129
# Optionally, specify the C++ compiler directly (here we use clang++)
1310
set(CMAKE_C_COMPILER clang)
1411
set(CMAKE_CXX_COMPILER clang++)
1512

13+
14+
option(SIMDJSON_SANITIZE_MEMORY "Sanitize memory" OFF)
15+
16+
if(SIMDJSON_SANITIZE_MEMORY)
17+
message(STATUS "Setting the memory sanitizer.")
18+
add_compile_options(
19+
-fsanitize=memory -fno-sanitize-recover=all
20+
)
21+
link_libraries(
22+
-fsanitize=memory -fno-sanitize-recover=all
23+
)
24+
endif()
25+
26+
if(NOT CMAKE_BUILD_TYPE)
27+
if(SIMDJSON_SANITIZE OR SIMDJSON_SANITIZE_UNDEFINED)
28+
message(STATUS "No build type selected and you have enabled the sanitizer, \
29+
default to Debug. Consider setting CMAKE_BUILD_TYPE.")
30+
message(STATUS "Setting debug optimization flag to -O1 to help sanitizer.")
31+
set(CMAKE_CXX_FLAGS_DEBUG "-O1" CACHE STRING "" FORCE)
32+
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
33+
else()
34+
message(STATUS "No build type selected, default to Release")
35+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
36+
endif()
37+
endif()
38+
39+
40+
# if(CMAKE_BUILD_TYPE STREQUAL "Debug")
41+
# set(CMAKE_C_FLAGS_DEBUG "-g -fsanitize=address,undefined -fno-omit-frame-pointer")
42+
# set(CMAKE_CXX_FLAGS_DEBUG "-g -fsanitize=address,undefined -fno-omit-frame-pointer")
43+
# else()
44+
# set(CMAKE_C_FLAGS_RELEASE "-O2 -fsanitize=address,undefined")
45+
# set(CMAKE_CXX_FLAGS_RELEASE "-O2 -fsanitize=address,undefined")
46+
# set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g -fsanitize=address,undefined")
47+
# set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -fsanitize=address,undefined")
48+
#endif()
49+
1650
# Include directories
1751
include_directories(${CMAKE_SOURCE_DIR})
1852

19-
# Add executable target
53+
# Add executable targets
2054
add_executable(SerializationBenchmark benchmark_serialization.cpp)
55+
add_executable(SerializationTwitterBenchmark benchmark_serialization_twitter.cpp)
2156

2257
target_compile_options(SerializationBenchmark PRIVATE -freflection -stdlib=libc++ -std=c++26)
23-
# If you have any libraries to link (e.g., if your project grows and you decide to compile some parts into a library),
24-
# you would specify them here with target_link_libraries(MyLibraryExample mylib)
58+
target_compile_options(SerializationTwitterBenchmark PRIVATE -freflection -stdlib=libc++ -std=c++26)
59+
60+
61+
# Link sanitizers and libraries
62+
target_link_libraries(SerializationTwitterBenchmark PRIVATE nlohmann_json::nlohmann_json simdjson::simdjson)
63+
target_link_libraries(SerializationBenchmark PRIVATE simdjson-serial nlohmann_json::nlohmann_json simdjson::simdjson)
2564

26-
target_link_libraries(SerializationBenchmark PRIVATE simdjson-serial nlohmann_json::nlohmann_json simdjson::simdjson)
65+
target_compile_definitions(SerializationTwitterBenchmark PRIVATE JSON_FILE="${PROJECT_SOURCE_DIR}/data/twitter.json")

benchmarks/src/apple_arm_events.h

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -356,17 +356,17 @@ static u64 (*kperf_ticks_to_ns)(u64 ticks);
356356
static u64 (*kperf_tick_frequency)(void);
357357

358358
/// Get lightweight PET mode (not in kperf.framework).
359-
static int kperf_lightweight_pet_get(u32 *enabled) {
359+
/*static int kperf_lightweight_pet_get(u32 *enabled) {
360360
if (!enabled)
361361
return -1;
362362
usize size = 4;
363363
return sysctlbyname("kperf.lightweight_pet", enabled, &size, NULL, 0);
364-
}
364+
}*/
365365

366366
/// Set lightweight PET mode (not in kperf.framework).
367-
static int kperf_lightweight_pet_set(u32 enabled) {
367+
/*static int kperf_lightweight_pet_set(u32 enabled) {
368368
return sysctlbyname("kperf.lightweight_pet", NULL, NULL, &enabled, 4);
369-
}
369+
}*/
370370

371371
// -----------------------------------------------------------------------------
372372
// <kperfdata.framework> header (reverse engineered)
@@ -834,57 +834,57 @@ typedef struct {
834834

835835
/// Clean up trace buffers and reset ktrace/kdebug/kperf.
836836
/// @return 0 on success.
837-
static int kdebug_reset(void) {
837+
/*static int kdebug_reset(void) {
838838
int mib[3] = {CTL_KERN, KERN_KDEBUG, KERN_KDREMOVE};
839839
return sysctl(mib, 3, NULL, NULL, NULL, 0);
840-
}
840+
}*/
841841

842842
/// Disable and reinitialize the trace buffers.
843843
/// @return 0 on success.
844-
static int kdebug_reinit(void) {
844+
/*static int kdebug_reinit(void) {
845845
int mib[3] = {CTL_KERN, KERN_KDEBUG, KERN_KDSETUP};
846846
return sysctl(mib, 3, NULL, NULL, NULL, 0);
847-
}
847+
}*/
848848

849849
/// Set debug filter.
850-
static int kdebug_setreg(kd_regtype *kdr) {
850+
/*static int kdebug_setreg(kd_regtype *kdr) {
851851
int mib[3] = {CTL_KERN, KERN_KDEBUG, KERN_KDSETREG};
852852
usize size = sizeof(kd_regtype);
853853
return sysctl(mib, 3, kdr, &size, NULL, 0);
854-
}
854+
}*/
855855

856856
/// Set maximum number of trace entries (kd_buf).
857857
/// Only allow allocation up to half the available memory (sane_size).
858858
/// @return 0 on success.
859-
static int kdebug_trace_setbuf(int nbufs) {
859+
/*static int kdebug_trace_setbuf(int nbufs) {
860860
int mib[4] = {CTL_KERN, KERN_KDEBUG, KERN_KDSETBUF, nbufs};
861861
return sysctl(mib, 4, NULL, NULL, NULL, 0);
862-
}
862+
}*/
863863

864864
/// Enable or disable kdebug trace.
865865
/// Trace buffer must already be initialized.
866866
/// @return 0 on success.
867-
static int kdebug_trace_enable(bool enable) {
867+
/*static int kdebug_trace_enable(bool enable) {
868868
int mib[4] = {CTL_KERN, KERN_KDEBUG, KERN_KDENABLE, enable};
869869
return sysctl(mib, 4, NULL, 0, NULL, 0);
870-
}
870+
}*/
871871

872872
/// Retrieve trace buffer information from kernel.
873873
/// @return 0 on success.
874-
static int kdebug_get_bufinfo(kbufinfo_t *info) {
874+
/*static int kdebug_get_bufinfo(kbufinfo_t *info) {
875875
if (!info)
876876
return -1;
877877
int mib[3] = {CTL_KERN, KERN_KDEBUG, KERN_KDGETBUF};
878878
size_t needed = sizeof(kbufinfo_t);
879879
return sysctl(mib, 3, info, &needed, NULL, 0);
880-
}
880+
}*/
881881

882882
/// Retrieve trace buffers from kernel.
883883
/// @param buf Memory to receive buffer data, array of `kd_buf`.
884884
/// @param len Length of `buf` in bytes.
885885
/// @param count Number of trace entries (kd_buf) obtained.
886886
/// @return 0 on success.
887-
static int kdebug_trace_read(void *buf, usize len, usize *count) {
887+
/*static int kdebug_trace_read(void *buf, usize len, usize *count) {
888888
if (count)
889889
*count = 0;
890890
if (!buf || !len)
@@ -899,13 +899,13 @@ static int kdebug_trace_read(void *buf, usize len, usize *count) {
899899
return ret;
900900
*count = len;
901901
return 0;
902-
}
902+
}*/
903903

904904
/// Block until there are new buffers filled or `timeout_ms` have passed.
905905
/// @param timeout_ms timeout milliseconds, 0 means wait forever.
906906
/// @param suc set true if new buffers filled.
907907
/// @return 0 on success.
908-
static int kdebug_wait(usize timeout_ms, bool *suc) {
908+
/*static int kdebug_wait(usize timeout_ms, bool *suc) {
909909
if (timeout_ms == 0)
910910
return -1;
911911
int mib[3] = {CTL_KERN, KERN_KDEBUG, KERN_KDBUFWAIT};
@@ -914,7 +914,7 @@ static int kdebug_wait(usize timeout_ms, bool *suc) {
914914
if (suc)
915915
*suc = !!val;
916916
return ret;
917-
}
917+
}*/
918918

919919
// -----------------------------------------------------------------------------
920920
// Demo

0 commit comments

Comments
 (0)