rails/rails — pull request #12065 by SamSaffron (2013-08-29 02:40:44+00:00)
Title: Perf: micro optimised Result column hash_row creation

This does replace rather elegant code with more verbose code, but for good reason.

With this change applied array allocation in AR is heavily reduced:

For a Discourse sample query I am seeing

Before:

```
T_ARRAY 10812
T_STRING 8891
T_HASH 1703
T_OBJECT 946
T_NODE 779
T_DATA 417
T_STRUCT 128
T_MATCH 15
T_REGEXP 5
T_CLASS 3
```

After:

```
T_STRING 8891
T_ARRAY 6553
T_HASH 1703
T_OBJECT 946
T_NODE 779
T_DATA 417
T_STRUCT 128
T_MATCH 15
T_REGEXP 5
T_CLASS 3
```

So T_ARRAY allocations are reduced from by almost half. A micro bench shows this is also faster cpu wise.

```ruby
require 'benchmark'

def zip_it(array1,array2)
Hash[array1.zip(array2)]
end

def naive(array1,array2)
hash = Hash.new

index = 0
length = array1.length
while index < length
hash[array1[index]] = array2[index]
index+=1
end

hash
end

[2,20,40,60,100].each do |i|

array1 = (0..i).to_a
array2 = (0..i).to_a

puts
puts "Benching #{i} elements"
puts

Benchmark.bmbm do |x|
x.report("zip #{i}") do
100000.times{zip_it(array1,array2)}
end

x.report("naive #{i}") do
100000.times{naive(array1,array2)}
end
end

end

```

Results:

```
sam@ubuntu:~/Source/play$ ruby fastest_arrays_to_hash.rb

Benching 2 elements

Rehearsal -------------------------------------------
zip 2 0.070000 0.000000 0.070000 ( 0.074535)
naive 2 0.050000 0.010000 0.060000 ( 0.057374)
---------------------------------- total: 0.130000sec

user system total real
zip 2 0.060000 0.000000 0.060000 ( 0.066469)
naive 2 0.060000 0.000000 0.060000 ( 0.057196)

Benching 20 elements

Rehearsal --------------------------------------------
zip 20 0.380000 0.000000 0.380000 ( 0.383691)
naive 20 0.350000 0.000000 0.350000 ( 0.354300)
----------------------------------- total: 0.730000sec

user system total real
zip 20 0.380000 0.000000 0.380000 ( 0.389739)
naive 20 0.350000 0.000000 0.350000 ( 0.347917)

Benching 40 elements

Rehearsal --------------------------------------------
zip 40 0.720000 0.000000 0.720000 ( 0.736159)
naive 40 0.660000 0.010000 0.670000 ( 0.670283)
----------------------------------- total: 1.390000sec

user system total real
zip 40 0.720000 0.000000 0.720000 ( 0.722527)
naive 40 0.660000 0.000000 0.660000 ( 0.664174)

Benching 60 elements

Rehearsal --------------------------------------------
zip 60 1.110000 0.000000 1.110000 ( 1.116779)
naive 60 0.780000 0.080000 0.860000 ( 0.870799)
----------------------------------- total: 1.970000sec

user system total real
zip 60 0.870000 0.000000 0.870000 ( 0.872703)
naive 60 0.710000 0.040000 0.750000 ( 0.745715)

Benching 100 elements

Rehearsal ---------------------------------------------
zip 100 1.700000 0.000000 1.700000 ( 1.712397)
naive 100 1.280000 0.060000 1.340000 ( 1.341964)
------------------------------------ total: 3.040000sec

user system total real
zip 100 1.490000 0.000000 1.490000 ( 1.502800)
naive 100 1.240000 0.000000 1.240000 ( 1.259484)

```