mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
[ruby/json] parser.c: Skip checking for escape sequences in rstring_cache_fetch
The caller already know if the string contains escape sequences so this check is redundant. Also stop calling `rstring_cache_fetch` from `json_string_unescape` as we know it won't match anyways. ``` == 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 122.000 i/100ms Calculating ------------------------------------- after 1.226k (± 0.3%) i/s (815.85 μs/i) - 6.222k in 5.076282s Comparison: before: 1206.2 i/s after: 1225.7 i/s - 1.02x faster ``` https://github.com/ruby/json/commit/b8cdf3282d Co-Authored-By: Scott Myron <samyron@gmail.com>
This commit is contained in:
parent
35a5e55133
commit
edebd83ea9
@ -122,12 +122,6 @@ static VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const lon
|
||||
}
|
||||
}
|
||||
|
||||
if (RB_UNLIKELY(memchr(str, '\\', length))) {
|
||||
// We assume the overwhelming majority of names don't need to be escaped.
|
||||
// But if they do, we have to fallback to the slow path.
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
VALUE rstring = build_interned_string(str, length);
|
||||
|
||||
if (cache->length < JSON_RVALUE_CACHE_CAPA) {
|
||||
@ -174,12 +168,6 @@ static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const lon
|
||||
}
|
||||
}
|
||||
|
||||
if (RB_UNLIKELY(memchr(str, '\\', length))) {
|
||||
// We assume the overwhelming majority of names don't need to be escaped.
|
||||
// But if they do, we have to fallback to the slow path.
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
VALUE rsymbol = build_symbol(str, length);
|
||||
|
||||
if (cache->length < JSON_RVALUE_CACHE_CAPA) {
|
||||
@ -652,19 +640,6 @@ static VALUE json_string_unescape(JSON_ParserState *state, const char *string, c
|
||||
int unescape_len;
|
||||
char buf[4];
|
||||
|
||||
if (is_name && state->in_array) {
|
||||
VALUE cached_key;
|
||||
if (RB_UNLIKELY(symbolize)) {
|
||||
cached_key = rsymbol_cache_fetch(&state->name_cache, string, bufferSize);
|
||||
} else {
|
||||
cached_key = rstring_cache_fetch(&state->name_cache, string, bufferSize);
|
||||
}
|
||||
|
||||
if (RB_LIKELY(cached_key)) {
|
||||
return cached_key;
|
||||
}
|
||||
}
|
||||
|
||||
VALUE result = rb_str_buf_new(bufferSize);
|
||||
rb_enc_associate_index(result, utf8_encindex);
|
||||
buffer = RSTRING_PTR(result);
|
||||
|
||||
@ -344,6 +344,18 @@ class JSONParserTest < Test::Unit::TestCase
|
||||
assert_equal orig, parse(json5)
|
||||
end
|
||||
|
||||
def test_parse_escaped_key
|
||||
doc = {
|
||||
"test\r1" => 1,
|
||||
"entries" => [
|
||||
"test\t2" => 2,
|
||||
"test\n3" => 3,
|
||||
]
|
||||
}
|
||||
|
||||
assert_equal doc, parse(JSON.generate(doc))
|
||||
end
|
||||
|
||||
def test_parse_duplicate_key
|
||||
expected = {"a" => 2}
|
||||
expected_sym = {a: 2}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user