<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/ext/json/fbuffer/fbuffer.h, branch v4.0.2</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>[ruby/json] Use #if instead of #ifdef when checking for JSON_DEBUG so debugging code is not generated when JSON_DEBUG=0.</title>
<updated>2025-11-18T08:20:51+00:00</updated>
<author>
<name>Scott Myron</name>
<email>samyron@gmail.com</email>
</author>
<published>2025-11-18T03:08:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f272aabb5c007d4a8f15e141edbd1bf2d079c5fc'/>
<id>f272aabb5c007d4a8f15e141edbd1bf2d079c5fc</id>
<content type='text'>
https://github.com/ruby/json/commit/4f1adb10d3
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/ruby/json/commit/4f1adb10d3
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/json] Centralize macro definitions</title>
<updated>2025-11-03T09:22:40+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-11-03T09:07:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=35a5e5513377d0d1f13c3ab15966a5c51b24066c'/>
<id>35a5e5513377d0d1f13c3ab15966a5c51b24066c</id>
<content type='text'>
https://github.com/ruby/json/commit/1576ea7d47
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/ruby/json/commit/1576ea7d47
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/json] Fix memory leak when exception is raised during JSON generation part 2</title>
<updated>2025-10-31T16:02:26+00:00</updated>
<author>
<name>Kazuki Yamaguchi</name>
<email>k@rhe.jp</email>
</author>
<published>2025-10-31T14:52:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6bdb2027f64df8e6f59273488ea01ed1614bcf76'/>
<id>6bdb2027f64df8e6f59273488ea01ed1614bcf76</id>
<content type='text'>
Commit https://github.com/ruby/json/commit/44df509dc2de fixed it for StandardError, but other exceptions and
jumps are also possible. Use rb_ensure() to release FBuffer instead of
rb_rescue().

A reproducer:

    o = Object.new
    def o.to_json(a) = throw :a
    a = ["make heap allocation"*100, o]

    10.times do
      100_000.times do
        catch(:a) { JSON(a) }
      end

      puts `ps -o rss= -p #{$$}`
    end

https://github.com/ruby/json/commit/9b7b648ecd
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Commit https://github.com/ruby/json/commit/44df509dc2de fixed it for StandardError, but other exceptions and
jumps are also possible. Use rb_ensure() to release FBuffer instead of
rb_rescue().

A reproducer:

    o = Object.new
    def o.to_json(a) = throw :a
    a = ["make heap allocation"*100, o]

    10.times do
      100_000.times do
        catch(:a) { JSON(a) }
      end

      puts `ps -o rss= -p #{$$}`
    end

https://github.com/ruby/json/commit/9b7b648ecd
</pre>
</div>
</content>
</entry>
<entry>
<title>JSON.generate: warn or raise on duplicated key</title>
<updated>2025-08-27T01:01:52+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-08-23T17:57:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=d9e9a667a8c8fb6f57611c68b45eaf1f2c39fca1'/>
<id>d9e9a667a8c8fb6f57611c68b45eaf1f2c39fca1</id>
<content type='text'>
Because both strings and symbols keys are serialized the same,
it always has been possible to generate documents with duplicated
keys:

```ruby
&gt;&gt; puts JSON.generate({ foo: 1, "foo" =&gt; 2 })
{"foo":1,"foo":2}
```

This is pretty much always a mistake and can cause various
issues because it's not guaranteed how various JSON parsers
will handle this.

Until now I didn't think it was possible to catch such case without
tanking performance, hence why I only made the parser more strict.

But I finally found a way to check for duplicated keys cheaply enough.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Because both strings and symbols keys are serialized the same,
it always has been possible to generate documents with duplicated
keys:

```ruby
&gt;&gt; puts JSON.generate({ foo: 1, "foo" =&gt; 2 })
{"foo":1,"foo":2}
```

This is pretty much always a mistake and can cause various
issues because it's not guaranteed how various JSON parsers
will handle this.

Until now I didn't think it was possible to catch such case without
tanking performance, hence why I only made the parser more strict.

But I finally found a way to check for duplicated keys cheaply enough.
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/json] Optimize `fbuffer_append_str_repeat`</title>
<updated>2025-08-27T01:01:52+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-08-24T15:39:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=97b5df11435d60d4dcdeb9474275cfc694d43b1e'/>
<id>97b5df11435d60d4dcdeb9474275cfc694d43b1e</id>
<content type='text'>
Helps with pretty printting performance:

```
== Encoding activitypub.json (52595 bytes)
ruby 3.4.2 (2025-02-15 revision https://github.com/ruby/json/commit/d2930f8e7a) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after     1.746k i/100ms
Calculating -------------------------------------
               after     17.481k (± 1.0%) i/s   (57.20 μs/i) -     89.046k in   5.094341s

Comparison:
              before:    16038.4 i/s
               after:    17481.1 i/s - 1.09x  faster

== Encoding citm_catalog.json (500298 bytes)
ruby 3.4.2 (2025-02-15 revision https://github.com/ruby/json/commit/d2930f8e7a) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after    60.000 i/100ms
Calculating -------------------------------------
               after    608.157 (± 2.3%) i/s    (1.64 ms/i) -      3.060k in   5.034238s

Comparison:
              before:      525.3 i/s
               after:      608.2 i/s - 1.16x  faster

== Encoding twitter.json (466906 bytes)
ruby 3.4.2 (2025-02-15 revision https://github.com/ruby/json/commit/d2930f8e7a) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after   160.000 i/100ms
Calculating -------------------------------------
               after      1.606k (± 0.5%) i/s  (622.70 μs/i) -      8.160k in   5.081406s

Comparison:
              before:     1410.3 i/s
               after:     1605.9 i/s - 1.14x  faster
```

https://github.com/ruby/json/commit/f0dda861c5
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Helps with pretty printting performance:

```
== Encoding activitypub.json (52595 bytes)
ruby 3.4.2 (2025-02-15 revision https://github.com/ruby/json/commit/d2930f8e7a) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after     1.746k i/100ms
Calculating -------------------------------------
               after     17.481k (± 1.0%) i/s   (57.20 μs/i) -     89.046k in   5.094341s

Comparison:
              before:    16038.4 i/s
               after:    17481.1 i/s - 1.09x  faster

== Encoding citm_catalog.json (500298 bytes)
ruby 3.4.2 (2025-02-15 revision https://github.com/ruby/json/commit/d2930f8e7a) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after    60.000 i/100ms
Calculating -------------------------------------
               after    608.157 (± 2.3%) i/s    (1.64 ms/i) -      3.060k in   5.034238s

Comparison:
              before:      525.3 i/s
               after:      608.2 i/s - 1.16x  faster

== Encoding twitter.json (466906 bytes)
ruby 3.4.2 (2025-02-15 revision https://github.com/ruby/json/commit/d2930f8e7a) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after   160.000 i/100ms
Calculating -------------------------------------
               after      1.606k (± 0.5%) i/s  (622.70 μs/i) -      8.160k in   5.081406s

Comparison:
              before:     1410.3 i/s
               after:     1605.9 i/s - 1.14x  faster
```

https://github.com/ruby/json/commit/f0dda861c5
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/json] Extract `fbuffer_append_str_repeat` function</title>
<updated>2025-08-27T01:01:52+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-08-23T19:04:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4d6b1241f628392cad79c8aef1477445514135f2'/>
<id>4d6b1241f628392cad79c8aef1477445514135f2</id>
<content type='text'>
https://github.com/ruby/json/commit/12656777dc
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/ruby/json/commit/12656777dc
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/json] fbuffer.c: add debug mode with bound checks.</title>
<updated>2025-05-26T02:46:12+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-05-23T09:27:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=212213a5526ee1768c3a972476967050443a25f6'/>
<id>212213a5526ee1768c3a972476967050443a25f6</id>
<content type='text'>
This would have caught https://github.com/ruby/json/pull/808
on CI.

https://github.com/ruby/json/commit/8109421fb4
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This would have caught https://github.com/ruby/json/pull/808
on CI.

https://github.com/ruby/json/commit/8109421fb4
</pre>
</div>
</content>
</entry>
<entry>
<title>Refactor jeaiii-ltoa.h</title>
<updated>2025-03-27T04:54:12+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-03-25T09:59:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4dde7101c722df3e1659ab0f4bee546afba9f3a5'/>
<id>4dde7101c722df3e1659ab0f4bee546afba9f3a5</id>
<content type='text'>
Some relatively minor change to make the library more in line
with the gem. Some renaming, etc.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Some relatively minor change to make the library more in line
with the gem. Some renaming, etc.
</pre>
</div>
</content>
</entry>
<entry>
<title>Removed trailing spaces</title>
<updated>2025-03-27T02:37:27+00:00</updated>
<author>
<name>Hiroshi SHIBATA</name>
<email>hsbt@ruby-lang.org</email>
</author>
<published>2025-03-27T01:12:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ee85745c616aa0dcd0bcf207708778a14c02816c'/>
<id>ee85745c616aa0dcd0bcf207708778a14c02816c</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Faster integer formatting</title>
<updated>2025-03-27T02:37:27+00:00</updated>
<author>
<name>eno</name>
<email>eno@open-lab.org</email>
</author>
<published>2025-03-16T18:51:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=d1f3c8125854bb0976b08dbcbda3524d8ea3e3fe'/>
<id>d1f3c8125854bb0976b08dbcbda3524d8ea3e3fe</id>
<content type='text'>
This commit provides an alternative implementation for a
long → decimal conversion.

The main difference is that it uses an algorithm pulled from
https://github.com/jeaiii/itoa.
The source there is C++, it was converted by hand to C for
inclusion with this gem.
jeaiii's algorithm is covered by the MIT License, see source code.

On addition this version now also generates the string directly into
the fbuffer, foregoing the need to run a separate memory copy.

As a result, I see a speedup of 32% on Apple Silicon M1 for an
integer set of benchmarks.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This commit provides an alternative implementation for a
long → decimal conversion.

The main difference is that it uses an algorithm pulled from
https://github.com/jeaiii/itoa.
The source there is C++, it was converted by hand to C for
inclusion with this gem.
jeaiii's algorithm is covered by the MIT License, see source code.

On addition this version now also generates the string directly into
the fbuffer, foregoing the need to run a separate memory copy.

As a result, I see a speedup of 32% on Apple Silicon M1 for an
integer set of benchmarks.
</pre>
</div>
</content>
</entry>
</feed>
