ruby-numo / numo-narray

Ruby/Numo::NArray - New NArray class library
http://ruby-numo.github.io/narray/
BSD 3-Clause "New" or "Revised" License
415 stars 41 forks source link

Arithmetic sequence support. #121

Closed naitoh closed 5 years ago

naitoh commented 5 years ago

I am working on supporting arithmetic sequences in Ruby 2.6. Please tell me because there are unclear points in this work.

Numo::NArray Slicing and Store List of patterns.

Ruby return Numo slicing support Numo store support api
object sample 2.5 2.6 return (value) return (class) now this PR now this PR to_a(Array) begin end first first(2) last last(2) step exclude_end? length
Array [1, 3, 5, 7, 9] o Array o o o o <= - - 1 [1, 3] 9 [7, 9] - - 10
Range 1..10 o 1..10 Range o o o o [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 1 10 1 [1, 2] 10 [9, 10] #<Enumerator: 1..10:step> FALSE -
1...10 o 1...10 Range o o o o [1, 2, 3, 4, 5, 6, 7, 8, 9] 1 10 1 [1, 2] 9 [8, 9] #<Enumerator: 1...10:step> TRUE -
Integer#step 1.step(10) o - #<Enumerator: 1:step(10)> Enumerable - - - - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - - 1 [1, 3] - - - - -
- o (1.step(10)) Enumerator::ArithmeticSequence - o - o [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 1 10 1 [1, 3] 10 [9, 10] 1 FALSE -
Integer#step 1.step(10, 2) o - #<Enumerator: 1:step(10, 2)> Enumerable - - - - [1, 3, 5, 7, 9] - - 1 [1, 3] - - - - -
- o (1.step(10, 2)) Enumerator::ArithmeticSequence - o - o [1, 3, 5, 7, 9] 1 10 1 [1, 3] 9 [7, 9] 2 FALSE -
Range#each (1..10).each o #<Enumerator: 1..10:each> Enumerable o o o o [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - - 1 [1, 2] - - - - -
Range#step (1..10).step(2) o - #<Enumerator: 1..10:step(2)> Enumerable o o o o [1, 3, 5, 7, 9] - - 1 [1, 3] - - - - -
- o ((1..10).step(2)) Enumerator::ArithmeticSequence o o o o [1, 3, 5, 7, 9] 1 10 1 [1, 3] 9 [7, 9] 2 FALSE -
(1...10).step(2) o - #<Enumerator: 1...10:step(2)> Enumerable o o o o [1, 3, 5, 7, 9] - - 1 [1, 3] - - - - -
- o ((1...10).step(2)) Enumerator::ArithmeticSequence o o o o [1, 3, 5, 7, 9] 1 10 1 [1, 3] 9 [7, 9] 2 TRUE -
Range#%
(step alias,
from 2.6)
(1..10) % 2 - o ((1..10).%(2)) Enumerator::ArithmeticSequence - o - o [1, 3, 5, 7, 9] 1 10 1 [1, 3] 9 [7, 9] 2 FALSE -
o o # Numo::NArray::Step o - o - - 1 10 1 - 10 - 2 FALSE nii
(1...10) % 2 - o ((1...10).%(2)) Enumerator::ArithmeticSequence - o - o [1, 3, 5, 7, 9] 1 10 1 [1, 3] 9 [7, 9] 2 TRUE -
o o # Numo::NArray::Step o - o - - 1 10 1 - 10 - 2 TRUE nil
(1...10) * 2

Question.

masa16 commented 5 years ago

I agree with Q3. I will remove the Numo::NArray::Step class.

naitoh commented 5 years ago

I agree with Q3. I will remove the Numo::NArray::Step class.

Thank you for your reply. I have completed the work with this pull request, please confirm.

The changes are as follows.

naitoh commented 5 years ago

I'm sorry. I confirmed the performance deterioration of #cast with Ruby 2.6.

I will investigate the cause. Please wait.

Ruby 2.6.0 (Linux)

$ benchmark-driver cast.yaml 
                                          numo-narray 0.9.1.4  numo-narray 0.9.2.0
Numo::Int64.cast(Numo::Int32(A).seq)                  48.630k              44.189k i/s -     10.000k times in 0.205634s 0.226301s
Numo::Int64.cast(Numo::Int32(A).seq.to_a)              1.178k              215.673 i/s -     10.000k times in 8.489695s 46.366547s
Numo::Int64[1..A]                                     17.954k              19.263k i/s -     10.000k times in 0.556987s 0.519135s
Numo::Int64[(1..B) % 2]                               18.949k              19.280k i/s -     10.000k times in 0.527734s 0.518675s

Comparison:
             Numo::Int64.cast(Numo::Int32(A).seq)     
                      numo-narray 0.9.1.4:     48630.1 i/s 
                      numo-narray 0.9.2.0:     44188.9 i/s - 1.10x  slower

             Numo::Int64.cast(Numo::Int32(A).seq.to_a)
                      numo-narray 0.9.1.4:      1177.9 i/s 
                      numo-narray 0.9.2.0:       215.7 i/s - 5.46x  slower

             Numo::Int64[1..A]                        
                      numo-narray 0.9.2.0:     19262.8 i/s 
                      numo-narray 0.9.1.4:     17953.7 i/s - 1.07x  slower

             Numo::Int64[(1..B) % 2]                  
                      numo-narray 0.9.2.0:     19279.9 i/s 
                      numo-narray 0.9.1.4:     18948.9 i/s - 1.02x  slower

Ruby 2.5.3 (Linux)

$ benchmark-driver cast.yaml 
                                          numo-narray 0.9.1.4  numo-narray 0.9.2.0 
Numo::Int64.cast(Numo::Int32(A).seq)                  57.024k              58.087k i/s -     10.000k times in 0.175364s 0.172154s
Numo::Int64.cast(Numo::Int32(A).seq.to_a)              1.251k               1.441k i/s -     10.000k times in 7.993797s 6.939518s
Numo::Int64[1..A]                                     18.220k              18.842k i/s -     10.000k times in 0.548839s 0.530729s
Numo::Int64[(1..B) % 2]                               17.571k              14.989k i/s -     10.000k times in 0.569118s 0.667175s

Comparison:
             Numo::Int64.cast(Numo::Int32(A).seq)     
                      numo-narray 0.9.2.0:     58087.4 i/s 
                      numo-narray 0.9.1.4:     57024.4 i/s - 1.02x  slower

             Numo::Int64.cast(Numo::Int32(A).seq.to_a)
                      numo-narray 0.9.2.0:      1441.0 i/s 
                      numo-narray 0.9.1.4:      1251.0 i/s - 1.15x  slower

             Numo::Int64[1..A]                        
                      numo-narray 0.9.2.0:     18842.0 i/s 
                      numo-narray 0.9.1.4:     18220.3 i/s - 1.03x  slower

             Numo::Int64[(1..B) % 2]                  
                      numo-narray 0.9.1.4:     17571.1 i/s 
                      numo-narray 0.9.2.0:     14988.6 i/s - 1.17x  slower

benchmark code

$ cat cast.yaml 
contexts:
  - gems: { numo-narray: 0.9.1.4 }
    require: false
    prelude: |
      require 'numo/narray'
  - gems: { numo-narray: 0.9.2.0 }
    require: false
    prelude: |
      require 'numo/narray'
loop_count: 10000
prelude: |
  require 'numo/narray'
  A = 10000
  B = A * 2
  y = Numo::Int32.new(A).seq
  z = Numo::Int32.new(A).seq.to_a
  sleep 5

benchmark:
  'Numo::Int64.cast(Numo::Int32(A).seq)     ' : Numo::Int64.cast(y)
  'Numo::Int64.cast(Numo::Int32(A).seq.to_a)' : Numo::Int64.cast(z)
  'Numo::Int64[1..A]                        ' : Numo::Int64[1..A]
  'Numo::Int64[(1..B) % 2]                  ' : Numo::Int64[(1..B) % 2]
naitoh commented 5 years ago

Thank you for merging this pull request!