[ruby-core:118485] [Ruby master Bug#20604] Performance regression in C++ extensions due to lack of optimization flags by default since Ruby 2.7
From:
"ntkme (Natsuki Natsume) via ruby-core" <ruby-core@...>
Date:
2024-07-08 16:13:24 UTC
List:
ruby-core #118485
Issue #20604 has been updated by ntkme (Natsuki Natsume).
This can be reproduced with the following benchmark script:
``` ruby
# frozen_string_literal: true
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'benchmark-ips'
gem 'bootstrap', '~> 5.3'
gem 'sassc'
end
BOOTSTRAP =3D Gem::Specification.find_by_name('bootstrap').gem_dir + '/asse=
ts/stylesheets/_bootstrap.scss'
require 'benchmark/ips'
require 'sassc'
Benchmark.ips do |x|
x.time =3D 15
x.report("CXXFLAGS=3D#{RbConfig::CONFIG["CXXFLAGS"].inspect}") do
SassC::Engine.new(File.read(BOOTSTRAP), { style: :compressed, filename:=
BOOTSTRAP }).render
end
x.compare!
end
```
Begin with the default on ruby:3.3 docker container with gcc 12.2.0.
Please make sure to `gem uninstall -a sassc` before the test to start clean.
```
ruby 3.3.3 (2024-06-12 revision f1c7b6f435) [aarch64-linux]
Warming up --------------------------------------
CXXFLAGS=3D"" 1.000 i/100ms
Calculating -------------------------------------
CXXFLAGS=3D"" 0.765 (=B1 0.0%) i/s - 12.000 in 15.684859s
```
Now edit `$RUBYARCHDIR/rbconfig.rb` to manually patch the default CXXFLAGS =
as the following:
```
CONFIG["CXXFLAGS"] =3D "$(optflags)"
```=20
Note: This file is read-only by default, and may need to be force overwritt=
en with depends on your editor.
Now we can run the same test again.
Please make sure to `gem uninstall -a sassc` before the test to start clean.
You can see this is about 7 times faster with `$optflags` on linux gcc.
```
ruby 3.3.3 (2024-06-12 revision f1c7b6f435) [aarch64-linux]
Warming up --------------------------------------
CXXFLAGS=3D"-O3 -fno-fast-math"
1.000 i/100ms
Calculating -------------------------------------
CXXFLAGS=3D"-O3 -fno-fast-math"
5.483 (=B1 0.0%) i/s - 83.000 in 15.139519s
```
---
I also tested on mac with clang 15 using homebrew ruby 3.3 out of box:
```
ruby 3.3.3 (2024-06-12 revision f1c7b6f435) [arm64-darwin23]
Warming up --------------------------------------
CXXFLAGS=3D"-fdeclspec"
1.000 i/100ms
Calculating -------------------------------------
CXXFLAGS=3D"-fdeclspec"
0.517 (=B1 0.0%) i/s - 8.000 in 15.475395s
```
It's more than 10 times faster with `$optflags` with clang 15 on mac:.
```
ruby 3.3.3 (2024-06-12 revision f1c7b6f435) [arm64-darwin23]
Warming up --------------------------------------
CXXFLAGS=3D"-fdeclspec -O3 -fno-fast-math"
1.000 i/100ms
Calculating -------------------------------------
CXXFLAGS=3D"-fdeclspec -O3 -fno-fast-math"
5.601 (=B1 0.0%) i/s - 85.000 in 15.177061s
```
----------------------------------------
Bug #20604: Performance regression in C++ extensions due to lack of optimiz=
ation flags by default since Ruby 2.7
https://bugs.ruby-lang.org/issues/20604#change-109006
* Author: ntkme (Natsuki Natsume)
* Status: Open
* ruby -v: ruby 3.3.3 (2024-06-12 revision f1c7b6f435) [arm64-darwin23]
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN
----------------------------------------
I found a significant performance regression in `sassc` gem when comparing =
Ruby 2.6 and later, that the extension is running more than 10x slower.
I have tracked it down to this commit: https://github.com/ruby/ruby/commit/=
733aa2f8b578d03bbcb91d2f496b01e3b990c7e8
This commit removed all default CXXFLAGS from RbConfig that were previously=
set, including `$optflags`, which has `-O3`.
Many of the C++ extensions like sassc use extconf/mkmf to compile, and they=
have assumed optflags are already set for CXXFLAGS. Without `-O3` as part =
of the default, the extensions are compiled without any optimizations and t=
hus become extremely slow.
It is difficult for a regular user to find out the reason of the slowness, =
nor to say figuring out how to override CXXFLAGS for a native extension.
I'm not sure what was the reason of the change, but I think we should at le=
ast set `$optflags` in CXXFLAGS by default.
--=20
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.rub=
y-lang.org/