[ruby-core:118419] [Ruby master Bug#20604] Performance regression in C++ extensions due to lack of optimization flags by default since Ruby 2.7

Issue #20604 has been reported by ntkme (Natsuki Natsume). ---------------------------------------- Bug #20604: Performance regression in C++ extensions due to lack of optimization flags by default since Ruby 2.7 https://bugs.ruby-lang.org/issues/20604 * 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 thus 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 least set `$optflags` in CXXFLAGS by default. -- https://bugs.ruby-lang.org/

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 = Gem::Specification.find_by_name('bootstrap').gem_dir + '/assets/stylesheets/_bootstrap.scss' require 'benchmark/ips' require 'sassc' Benchmark.ips do |x| x.time = 15 x.report("CXXFLAGS=#{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="" 1.000 i/100ms Calculating ------------------------------------- CXXFLAGS="" 0.765 (± 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"] = "$(optflags)" ``` Note: This file is read-only by default, and may need to be force overwritten 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="-O3 -fno-fast-math" 1.000 i/100ms Calculating ------------------------------------- CXXFLAGS="-O3 -fno-fast-math" 5.483 (± 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="-fdeclspec" 1.000 i/100ms Calculating ------------------------------------- CXXFLAGS="-fdeclspec" 0.517 (± 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="-fdeclspec -O3 -fno-fast-math" 1.000 i/100ms Calculating ------------------------------------- CXXFLAGS="-fdeclspec -O3 -fno-fast-math" 5.601 (± 0.0%) i/s - 85.000 in 15.177061s ``` ---------------------------------------- Bug #20604: Performance regression in C++ extensions due to lack of optimization 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 thus 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 least set `$optflags` in CXXFLAGS by default. -- https://bugs.ruby-lang.org/

Issue #20604 has been updated by shyouhei (Shyouhei Urabe). Status changed from Open to Rejected This is NG. Some OSes (if I remember correctly it was Arch when we found this) ship clang and g++ combination. They happen to have -O3 in common but not everything. It was a wrong idea first place for us to share $optflags. There's nothing we can do here. Please specify $CXXFLAGS individually. ---------------------------------------- Bug #20604: Performance regression in C++ extensions due to lack of optimization flags by default since Ruby 2.7 https://bugs.ruby-lang.org/issues/20604#change-109099 * Author: ntkme (Natsuki Natsume) * Status: Rejected * 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 thus 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 least set `$optflags` in CXXFLAGS by default. -- https://bugs.ruby-lang.org/

Issue #20604 has been updated by alanwu (Alan Wu).
Please specify $CXXFLAGS individually.
Just some additional information about how to do this. If you maintain a gem, you can add the desired flags to $CXXFLAGS in your `extconf.rb`. As an user, you can install a gem while adding to $CXXFLAGS using `--with-cxxflags` without changing the gem. This is an `mkmf` feature. For example: ``` $ gem install sassc -- --with-cxxflags=-O3 ``` ---------------------------------------- Bug #20604: Performance regression in C++ extensions due to lack of optimization flags by default since Ruby 2.7 https://bugs.ruby-lang.org/issues/20604#change-109100 * Author: ntkme (Natsuki Natsume) * Status: Rejected * 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 thus 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 least set `$optflags` in CXXFLAGS by default. -- https://bugs.ruby-lang.org/
participants (3)
-
alanwu (Alan Wu)
-
ntkme (Natsuki Natsume)
-
shyouhei (Shyouhei Urabe)