@mame (Yusuke Endoh) re benchmark
So I decided to run this against redmine boot, using this branch: https://github.com/redmine/redmine/compare/master...byroot:boot-benchmark
Eager loading is enabled so that the entire codebase is loaded, and it uses https://github.com/SamSaffron/memory_profiler to measure allocations and retentions.
Full benchmark output: https://gist.github.com/byroot/845a5877c1cde91c50b43be446dfb20f
Baseline (official 2.6.3):
Total allocated: 121.11 MB (1234362 objects)
Total retained: 24.86 MB (200539 objects)
allocated memory by class
-----------------------------------
63.36 MB String
allocated objects by class
-----------------------------------
980623 String
With the patch (official 2.6.3 + this patch):
Total allocated: 120.01 MB (1206699 objects)
Total retained: 24.82 MB (199397 objects)
allocated memory by class
-----------------------------------
62.25 MB String
allocated objects by class
-----------------------------------
952953 String
Diff:
-27 663 allocations (-2.24%)
-1.10MB allocations (-0.9%)
-1 142 retentions (-0.57%)
-0.4MB retentions (-0.16%)
IMHO that is significant, especially for a small sized application like Redmine. However I can't say wether it outweigh the backward compatibility concern or not.
Backward compatibility¶
One thing to note is that I had to patch https://github.com/rails/rails/blob/28aca474d48b6acdbe8c7861d9347e27c65fafd9/activesupport/lib/active_support/ordered_options.rb#L43 because it was mutating the result of Symbol#to_s
. Also running the Redmine test suite shows a couple breakage in the i18n gem.
IMHO these are fairly simple to fix, but I would totally understand if that was considered as a no-go.
Typical code benefiting from this change¶
- Rails autoloader and Zeitwerk would both benefit from the
Module#name
change as they both keep references to class names as hash keys
- Various parts of Rails would benefit as well since they use the class names extensively to derive other class names, as well as symbols
belongs_to :post
.
-
def method_missing
very often call name.to_s
to match the method name, hence would benefit from the Symbol#to_s
as well.
- Serialization of symbols into various formats, e.g.
{foo: 42}.to_json
. That pattern is fairly common IMO.