Bug #14599
closedImprove Pathname performance
Description
If it will not use special variables (like $1, $&, $`...),
it can improve the performance by using Regexp#match? instead of Regexp#=. will generate the objects to special variables by pattern matching.
Because Regexp#=
This patch will replace Regexp#=~ without special variables to Regexp#match?.
(Excludes https://github.com/ruby/ruby/blob/trunk/ext/pathname/lib/pathname.rb#L144-L153)
Environment¶
- OS : Ubuntu 17.10
- Compiler : gcc version 7.2.0
- CPU : Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
- Memory : 16 GB
TL;DR¶
| before | after | Speed up | |
|---|---|---|---|
| Pathname#absolute? | 142836 | 198487 | 39.0% |
| Pathname#cleanpath | 60706 | 79415 | 30.8% |
| Pathname#root? | 603806 | 759157 | 25.7% |
| Pathname#absolute? | 142592 | 197859 | 38.8% |
| Pathname#each_filename | 115600 | 152982 | 32.3% |
| Pathname#ascend | 50494 | 63606 | 26.0% |
| Pathname#+ | 100550 | 130372 | 29.7% |
| Pathname#join | 46673 | 60994 | 30.7% |
| Pathname#relative_path_from | 28362 | 37494 | 32.2% |
Before¶
Calculating ------------------------------------- Pathname#absolute? 142.836k (± 0.1%) i/s - 722.304k in 5.056884s Pathname#cleanpath 60.706k (± 0.1%) i/s - 306.764k in 5.053305s Pathname#root? 603.806k (± 0.3%) i/s - 3.062M in 5.071696s Pathname#absolute? 142.592k (± 0.1%) i/s - 720.846k in 5.055301s Pathname#each_filename 115.600k (± 0.1%) i/s - 586.818k in 5.076292s Pathname#ascend 50.494k (± 0.1%) i/s - 255.301k in 5.056049s Pathname#+ 100.550k (± 0.1%) i/s - 509.630k in 5.068433s Pathname#join 46.673k (± 0.1%) i/s - 236.433k in 5.065696s Pathname#relative_path_from 28.362k (± 0.0%) i/s - 143.728k in 5.067640s After¶
Calculating ------------------------------------- Pathname#absolute? 198.487k (± 0.1%) i/s - 995.665k in 5.016272s Pathname#cleanpath 79.415k (± 0.1%) i/s - 404.406k in 5.092344s Pathname#root? 759.157k (± 0.0%) i/s - 3.800M in 5.005072s Pathname#absolute? 197.859k (± 0.1%) i/s - 995.720k in 5.032494s Pathname#each_filename 152.982k (± 0.1%) i/s - 775.555k in 5.069607s Pathname#ascend 63.606k (± 0.0%) i/s - 320.862k in 5.044560s Pathname#+ 130.372k (± 0.1%) i/s - 660.856k in 5.068991s Pathname#join 60.994k (± 0.1%) i/s - 305.068k in 5.001626s Pathname#relative_path_from 37.494k (± 0.4%) i/s - 189.124k in 5.044146s Benchmark code¶
require 'pathname' require 'benchmark/ips' Benchmark.ips do |x| root = Pathname.new('/') path1 = Pathname.new('/path/to/some/file1.rb') path2 = Pathname.new('/path/to/some/file2.rb') x.report("Pathname#absolute?") do path1.absolute? end x.report("Pathname#cleanpath") do Pathname.new('/path/to/some/file.rb').cleanpath end x.report("Pathname#root?") do path1.root? end x.report("Pathname#absolute?") do path1.absolute? end x.report("Pathname#each_filename") do path1.each_filename { |file| } end x.report("Pathname#ascend") do path1.ascend { |path| } end x.report("Pathname#+") do path1 + path2 end x.report("Pathname#join") do path1.join("../file3.rb") end x.report("Pathname#relative_path_from") do path1.relative_path_from(root) end end Patch¶
Updated by watson1978 (Shizuo Fujita) over 7 years ago
- Status changed from Open to Closed
Applied in changeset trunk|r62740.
Improve Pathname performance
If it will not use special variables (like $1, $&, $`...),
it can improve the performance by using Regexp#match? instead of Regexp#=. will generate the objects to special variables by pattern matching.
Because Regexp#=
This patch will replace Regexp#=~ without special variables to Regexp#match?.
(Excludes https://github.com/ruby/ruby/blob/trunk/ext/pathname/lib/pathname.rb#L144-L153)
[Fix GH-1836] [ruby-core:86093] [Bug #14599]
Environment¶
- OS : Ubuntu 17.10
- Compiler : gcc version 7.2.0
- CPU : Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
- Memory : 16 GB
TL;DR¶
| Before | After | Speed up | |
|---|---|---|---|
| Pathname#absolute? | 142836 | 198487 | 39.0% |
| Pathname#cleanpath | 60706 | 79415 | 30.8% |
| Pathname#root? | 603806 | 759157 | 25.7% |
| Pathname#absolute? | 142592 | 197859 | 38.8% |
| Pathname#each_filename | 115600 | 152982 | 32.3% |
| Pathname#ascend | 50494 | 63606 | 26.0% |
| Pathname#+ | 100550 | 130372 | 29.7% |
| Pathname#join | 46673 | 60994 | 30.7% |
| Pathname#relative_path_from | 28362 | 37494 | 32.2% |
Before¶
Calculating ------------------------------------- Pathname#absolute? 142.836k (± 0.1%) i/s - 722.304k in 5.056884s Pathname#cleanpath 60.706k (± 0.1%) i/s - 306.764k in 5.053305s Pathname#root? 603.806k (± 0.3%) i/s - 3.062M in 5.071696s Pathname#absolute? 142.592k (± 0.1%) i/s - 720.846k in 5.055301s Pathname#each_filename 115.600k (± 0.1%) i/s - 586.818k in 5.076292s Pathname#ascend 50.494k (± 0.1%) i/s - 255.301k in 5.056049s Pathname#+ 100.550k (± 0.1%) i/s - 509.630k in 5.068433s Pathname#join 46.673k (± 0.1%) i/s - 236.433k in 5.065696s Pathname#relative_path_from 28.362k (± 0.0%) i/s - 143.728k in 5.067640s After¶
Calculating ------------------------------------- Pathname#absolute? 198.487k (± 0.1%) i/s - 995.665k in 5.016272s Pathname#cleanpath 79.415k (± 0.1%) i/s - 404.406k in 5.092344s Pathname#root? 759.157k (± 0.0%) i/s - 3.800M in 5.005072s Pathname#absolute? 197.859k (± 0.1%) i/s - 995.720k in 5.032494s Pathname#each_filename 152.982k (± 0.1%) i/s - 775.555k in 5.069607s Pathname#ascend 63.606k (± 0.0%) i/s - 320.862k in 5.044560s Pathname#+ 130.372k (± 0.1%) i/s - 660.856k in 5.068991s Pathname#join 60.994k (± 0.1%) i/s - 305.068k in 5.001626s Pathname#relative_path_from 37.494k (± 0.4%) i/s - 189.124k in 5.044146s Benchmark code¶
require 'pathname' require 'benchmark/ips' Benchmark.ips do |x| root = Pathname.new('/') path1 = Pathname.new('/path/to/some/file1.rb') path2 = Pathname.new('/path/to/some/file2.rb') x.report("Pathname#absolute?") do path1.absolute? end x.report("Pathname#cleanpath") do Pathname.new('/path/to/some/file.rb').cleanpath end x.report("Pathname#root?") do path1.root? end x.report("Pathname#absolute?") do path1.absolute? end x.report("Pathname#each_filename") do path1.each_filename { |file| } end x.report("Pathname#ascend") do path1.ascend { |path| } end x.report("Pathname#+") do path1 + path2 end x.report("Pathname#join") do path1.join("../file3.rb") end x.report("Pathname#relative_path_from") do path1.relative_path_from(root) end end