Issue #11158 has been updated by Koichi Sasada.


I don't against introduce Symbol.each for shortcut of Symbol.all_symbols.each.

However, For measurement purpose, we should introduce new measurement API into ObjectSpace because they have several types.

```
         immortal | mortal
--------+---------+--------
static  |   (1)   |   (2)
dynamic |   (3)   |   (4)
```

* Immortal symbols
  * Static immortal symbols (1)
  * Dynamic immortal symbols (3)
* Dynamic mortal symbols (4)

There are no (2) type symbols.

Current Symbol.all_symbols.size returns (1) + (3) + (4).
Maybe the number of (1) and (2) (or (1+2)) will be helpful for some kind ofpeople who want to know details.


----------------------------------------
Feature #11158: Introduce a Symbol.count API as a more efficient alternative to Symbol.all_symbols.size
https://bugs.ruby-lang.org/issues/11158#change-52897

* Author: Lourens Naud
* Status: Open
* Priority: Normal
* Assignee: Koichi Sasada
----------------------------------------
We're in the process of migrating a very large Rails codebase from a Ruby 2.1.6 runtime to Ruby 2.2.2 and as part of this migration process would liketo keep track of Symbol counts and Symbol GC efficiency in our metrics system. Preferably still while on 2.1 (however this implies a backport to 2.1 as well), but would definitely be useful in 2.2 as well.

Currently the recommended and only reliable way to get to the Symbol countsis via Symbol.all_symbols.size, which:

* Allocates an Array
* rb_ary_push and walking the symbol table isn't exactly efficient

Here's some benchmarks:

~~~
./miniruby -Ilib -rbenchmark -e "p Benchmark.measure { 10_000.times{ Symbol.count } }"
#<Benchmark::Tms:0x007f8bc208bdd0 @label="", @real=0.0011274919961579144, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=0.01, @total=0.01>
~~~

~~~
./miniruby -Ilib -rbenchmark -e "p Benchmark.measure { 10_000.times{ Symbol.all_symbols.size } }"
#<Benchmark::Tms:0x007fa47205a550 @label="", @real=0.3135859479953069, @cstime=0.0, @cutime=0.0, @stime=0.03, @utime=0.29, @total=0.31999999999999995>
~~~

I implemented and attached a patch for a simple Symbol.count API that just returns a numeric version of the symbol table size, without having to do any iteration.

Please let me know if this is inline with an expected core API, anything I could clean up further and if there's any possibility of such a change alsobeing backported to 2.1 as well? (happy to create a new patch for 2.1)

---Files--------------------------------
symbol_count.patch (4.4 KB)
symbol_enumerator.patch (6.07 KB)


-- 
https://bugs.ruby-lang.org/