diff options
author | Watson <watson1978@gmail.com> | 2018-03-04 23:34:26 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2019-10-14 19:54:48 +0900 |
commit | 641136c4af89ec2bc1f2c80aeefc7a38f3bc48df (patch) | |
tree | 66c09141827b90f62c6a82acee621a395f29efde /ext | |
parent | d9e50fcbeb34534d065f3662b6b952bc57994b43 (diff) | |
download | ruby-641136c4af89ec2bc1f2c80aeefc7a38f3bc48df.tar.gz |
[flori/json] Does not check whether illegal utf-8 if string has ascii only.
## Before
```
$ ruby bench_json_generate.rb
Warming up --------------------------------------
json 25.000 i/100ms
Calculating -------------------------------------
json 250.478 (± 4.8%) i/s - 1.250k in 5.002238s
```
## After
```
$ ruby bench_json_generate.rb
Warming up --------------------------------------
json 32.000 i/100ms
Calculating -------------------------------------
json 360.652 (± 3.6%) i/s - 1.824k in 5.064511s
```
## Test code
```
require 'json'
require 'benchmark/ips'
obj = []
1000.times do |i|
obj << {
:string => "x" * 100,
:utf8 => "あ" * 100
}
end
Benchmark.ips do |x|
x.report "json" do |iter|
count = 0
while count < iter
JSON.generate(obj)
count += 1
end
end
end
```
https://github.com/flori/json/commit/91a24ecac3
Diffstat (limited to 'ext')
-rw-r--r-- | ext/json/generator/generator.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 036205d7cb..cdf55c5ba4 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -237,6 +237,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string) int escape_len; unsigned char c; char buf[6] = { '\\', 'u' }; + int ascii_only = rb_enc_str_asciionly_p(string); for (start = 0, end = 0; end < len;) { p = ptr + end; @@ -281,14 +282,17 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string) break; default: { - unsigned short clen = trailingBytesForUTF8[c] + 1; - if (end + clen > len) { - rb_raise(rb_path2class("JSON::GeneratorError"), - "partial character in source, but hit end"); - } - if (!isLegalUTF8((UTF8 *) p, clen)) { - rb_raise(rb_path2class("JSON::GeneratorError"), - "source sequence is illegal/malformed utf-8"); + unsigned short clen = 1; + if (!ascii_only) { + clen += trailingBytesForUTF8[c]; + if (end + clen > len) { + rb_raise(rb_path2class("JSON::GeneratorError"), + "partial character in source, but hit end"); + } + if (!isLegalUTF8((UTF8 *) p, clen)) { + rb_raise(rb_path2class("JSON::GeneratorError"), + "source sequence is illegal/malformed utf-8"); + } } end += clen; } |