[ruby-cvs:69891] watson1978:r62740 (trunk): Improve Pathname performance

watson1978 at ruby-lang.org watson1978 at ruby-lang.org
Tue Mar 13 18:15:10 JST 2018


watson1978	2018-03-13 18:15:10 +0900 (Tue, 13 Mar 2018)

  New Revision: 62740

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62740

  Log:
    Improve Pathname performance
    
    If it will not use special variables (like $1, $&, $`...),
    it can improve the performance by using Regexp#match? instead of Regexp#=~.
    Because Regexp#=~ will generate the objects to special variables by pattern matching.
    
    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
    ?\194?\160                           | 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 (?\194?\177 0.1%) i/s -    722.304k in   5.056884s
      Pathname#cleanpath     60.706k (?\194?\177 0.1%) i/s -    306.764k in   5.053305s
          Pathname#root?    603.806k (?\194?\177 0.3%) i/s -      3.062M in   5.071696s
      Pathname#absolute?    142.592k (?\194?\177 0.1%) i/s -    720.846k in   5.055301s
    Pathname#each_filename
                            115.600k (?\194?\177 0.1%) i/s -    586.818k in   5.076292s
         Pathname#ascend     50.494k (?\194?\177 0.1%) i/s -    255.301k in   5.056049s
              Pathname#+    100.550k (?\194?\177 0.1%) i/s -    509.630k in   5.068433s
           Pathname#join     46.673k (?\194?\177 0.1%) i/s -    236.433k in   5.065696s
    Pathname#relative_path_from
                             28.362k (?\194?\177 0.0%) i/s -    143.728k in   5.067640s
    ```
    
    ## After
    ```
    Calculating -------------------------------------
      Pathname#absolute?    198.487k (?\194?\177 0.1%) i/s -    995.665k in   5.016272s
      Pathname#cleanpath     79.415k (?\194?\177 0.1%) i/s -    404.406k in   5.092344s
          Pathname#root?    759.157k (?\194?\177 0.0%) i/s -      3.800M in   5.005072s
      Pathname#absolute?    197.859k (?\194?\177 0.1%) i/s -    995.720k in   5.032494s
    Pathname#each_filename
                            152.982k (?\194?\177 0.1%) i/s -    775.555k in   5.069607s
         Pathname#ascend     63.606k (?\194?\177 0.0%) i/s -    320.862k in   5.044560s
              Pathname#+    130.372k (?\194?\177 0.1%) i/s -    660.856k in   5.068991s
           Pathname#join     60.994k (?\194?\177 0.1%) i/s -    305.068k in   5.001626s
    Pathname#relative_path_from
                             37.494k (?\194?\177 0.4%) i/s -    189.124k in   5.044146s
    ```
    
    ## Benchmark code
    ```ruby
    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
    ```

  Modified files:
    trunk/ext/pathname/lib/pathname.rb


More information about the ruby-cvs mailing list