From c49e4db680895735643d1001b2a0e4f405f49021 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 3 Nov 2025 14:10:02 +0100 Subject: [PATCH 1/4] [ruby/json] parser.c: Always inline `json_eat_whitespace` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` == Parsing activitypub.json (58160 bytes) ruby 3.4.6 (2025-09-16 revision https://github.com/ruby/json/commit/dbd83256b1) +YJIT +PRISM [arm64-darwin24] Warming up -------------------------------------- after 1.174k i/100ms Calculating ------------------------------------- after 11.756k (± 0.9%) i/s (85.06 μs/i) - 59.874k in 5.093438s Comparison: before: 11078.6 i/s after: 11756.1 i/s - 1.06x faster == Parsing twitter.json (567916 bytes) ruby 3.4.6 (2025-09-16 revision https://github.com/ruby/json/commit/dbd83256b1) +YJIT +PRISM [arm64-darwin24] Warming up -------------------------------------- after 130.000 i/100ms Calculating ------------------------------------- after 1.340k (± 0.3%) i/s (746.06 μs/i) - 6.760k in 5.043432s Comparison: before: 1191.1 i/s after: 1340.4 i/s - 1.13x faster == Parsing citm_catalog.json (1727030 bytes) ruby 3.4.6 (2025-09-16 revision https://github.com/ruby/json/commit/dbd83256b1) +YJIT +PRISM [arm64-darwin24] Warming up -------------------------------------- after 68.000 i/100ms Calculating ------------------------------------- after 689.451 (± 1.6%) i/s (1.45 ms/i) - 3.468k in 5.031470s Comparison: before: 630.3 i/s after: 689.5 i/s - 1.09x faster == Parsing float parsing (2251051 bytes) ruby 3.4.6 (2025-09-16 revision https://github.com/ruby/json/commit/dbd83256b1) +YJIT +PRISM [arm64-darwin24] Warming up -------------------------------------- after 27.000 i/100ms Calculating ------------------------------------- after 248.265 (± 0.8%) i/s (4.03 ms/i) - 1.242k in 5.003185s Comparison: before: 232.7 i/s after: 248.3 i/s - 1.07x faster ``` https://github.com/ruby/json/commit/043880f6ab Co-Authored-By: Scott Myron --- ext/json/parser/parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c index 25eeb89e773f1b..20754249e2ca39 100644 --- a/ext/json/parser/parser.c +++ b/ext/json/parser/parser.c @@ -513,7 +513,7 @@ json_eat_comments(JSON_ParserState *state) } } -static inline void +static ALWAYS_INLINE() void json_eat_whitespace(JSON_ParserState *state) { while (true) { From 4740b3d7aab216e83f069c4d2f26edfa3aeb1709 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 3 Nov 2025 07:39:00 -0800 Subject: [PATCH 2/4] [ruby/json] Fix check_dependency --- ext/json/generator/depend | 1 + ext/json/parser/depend | 1 + 2 files changed, 2 insertions(+) diff --git a/ext/json/generator/depend b/ext/json/generator/depend index aee4ab94ebcce8..3ba4acfdd26156 100644 --- a/ext/json/generator/depend +++ b/ext/json/generator/depend @@ -178,6 +178,7 @@ generator.o: $(hdrdir)/ruby/ruby.h generator.o: $(hdrdir)/ruby/st.h generator.o: $(hdrdir)/ruby/subst.h generator.o: $(srcdir)/../fbuffer/fbuffer.h +generator.o: $(srcdir)/../json.h generator.o: $(srcdir)/../simd/simd.h generator.o: $(srcdir)/../vendor/fpconv.c generator.o: $(srcdir)/../vendor/jeaiii-ltoa.h diff --git a/ext/json/parser/depend b/ext/json/parser/depend index b780afb5f94546..d4737b1dfb5b63 100644 --- a/ext/json/parser/depend +++ b/ext/json/parser/depend @@ -175,6 +175,7 @@ parser.o: $(hdrdir)/ruby/ruby.h parser.o: $(hdrdir)/ruby/st.h parser.o: $(hdrdir)/ruby/subst.h parser.o: $(srcdir)/../fbuffer/fbuffer.h +parser.o: $(srcdir)/../json.h parser.o: $(srcdir)/../simd/simd.h parser.o: $(srcdir)/../vendor/ryu.h parser.o: parser.c From 2f9e0d355ef4db3157a401da8bf3b8da4c811d6b Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 3 Nov 2025 16:55:42 +0100 Subject: [PATCH 3/4] [ruby/json] Fix duplicate 'inline' declaration specifier Followup: https://github.com/ruby/json/pull/889 https://github.com/ruby/json/commit/591510392a --- ext/json/generator/generator.c | 2 +- ext/json/simd/simd.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 56aa636ef87cc0..8930213b939a0d 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -418,7 +418,7 @@ static ALWAYS_INLINE() unsigned char sse2_next_match(search_state *search) #define TARGET_SSE2 #endif -static inline TARGET_SSE2 ALWAYS_INLINE() unsigned char search_escape_basic_sse2(search_state *search) +static TARGET_SSE2 ALWAYS_INLINE() unsigned char search_escape_basic_sse2(search_state *search) { if (RB_UNLIKELY(search->has_matches)) { // There are more matches if search->matches_mask > 0. diff --git a/ext/json/simd/simd.h b/ext/json/simd/simd.h index 194baee51c3475..a4f917fd0ae518 100644 --- a/ext/json/simd/simd.h +++ b/ext/json/simd/simd.h @@ -136,7 +136,7 @@ static inline uint8x16x4_t load_uint8x16_4(const unsigned char *table) #define _mm_cmpgt_epu8(a, b) _mm_xor_si128(_mm_cmple_epu8(a, b), _mm_set1_epi8(-1)) #define _mm_cmplt_epu8(a, b) _mm_cmpgt_epu8(b, a) -static inline TARGET_SSE2 ALWAYS_INLINE() int compute_chunk_mask_sse2(const char *ptr) +static TARGET_SSE2 ALWAYS_INLINE() int compute_chunk_mask_sse2(const char *ptr) { __m128i chunk = _mm_loadu_si128((__m128i const*)ptr); // Trick: c < 32 || c == 34 can be factored as c ^ 2 < 33 @@ -147,7 +147,7 @@ static inline TARGET_SSE2 ALWAYS_INLINE() int compute_chunk_mask_sse2(const char return _mm_movemask_epi8(needs_escape); } -static inline TARGET_SSE2 ALWAYS_INLINE() int string_scan_simd_sse2(const char **ptr, const char *end, int *mask) +static TARGET_SSE2 ALWAYS_INLINE() int string_scan_simd_sse2(const char **ptr, const char *end, int *mask) { while (*ptr + sizeof(__m128i) <= end) { int chunk_mask = compute_chunk_mask_sse2(*ptr); From 505fcf5dcfb59e91ed97e770b166793e44845bd8 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 3 Nov 2025 18:02:10 +0100 Subject: [PATCH 4/4] [ruby/json] ext/json/ext/json.h: Add missing newline at end of file https://github.com/ruby/json/commit/3bc1787bd4 --- ext/json/json.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/json/json.h b/ext/json/json.h index 873440527dec60..20e7101de7b0da 100644 --- a/ext/json/json.h +++ b/ext/json/json.h @@ -82,4 +82,4 @@ typedef unsigned char _Bool; #endif #endif -#endif // _JSON_H_ \ No newline at end of file +#endif // _JSON_H_