lanej/cistern — pull request #44 by jlindley (2014-11-15 00:22:51+00:00)
Title: 75% fewer Symbol#to_s calls in merge_attributes

In awsm, create_current_user ends up calling Symbol#to_s 1.6 million times
per invocation. 1.4 million of those come from Cistern's merge_attributes.

This patch converts the incoming key to a string and a symbol variant, once
each, and only uses those for its work. On average each key version of the
symbol was being converted to a string again 4 times in this method.

---

Awsm travis runs with and without:

with optimization: ran for ran for 14 hrs 48 min 31 sec
https://magnum.travis-ci.com/engineyard/awsm/builds/7465897

without optimization: ran for 17 hrs 9 min 48 sec
https://magnum.travis-ci.com/engineyard/awsm/builds/7463787

So, ~86% of the time to run whole awsm suite with this change.

---

Before: Symbol#to_s called 1.6 million times in each create_current_user

Calls:

Total: 18.778550

%self total self wait child calls name
9.01 3.179 1.692 0.000 1.487 775 Array#sort!
6.32 1.187 1.187 0.000 0.000 1564786 Symbol#to_s
3.56 0.669 0.669 0.000 0.000 944 #caller
3.07 0.577 0.577 0.000 0.000 565138 Kernel#hash

Time-per create_current_user benchmark

user system total real
3.300000 0.060000 3.360000 ( 3.495115)
2.980000 0.050000 3.030000 ( 3.168694)
3.000000 0.040000 3.040000 ( 3.189597)
3.020000 0.050000 3.070000 ( 3.219720)
3.000000 0.050000 3.050000 ( 3.191496)
3.010000 0.050000 3.060000 ( 3.190507)
3.020000 0.050000 3.070000 ( 3.206198)
2.990000 0.050000 3.040000 ( 3.179688)
3.040000 0.050000 3.090000 ( 3.231775)

---

After: Symbol#to_s called 0.4 million times in each create_current_user

Calls:

Total: 11.640456

%self total self wait child calls name
4.24 0.493 0.493 0.000 0.000 455451 Kernel#hash
3.12 0.680 0.363 0.000 0.316 168 Array#sort!
2.35 0.997 0.274 0.000 0.723 46069 DataMapper::Property#hash
2.28 0.266 0.266 0.000 0.000 369464 Symbol#to_s

Time-per create_current_user benchmark

user system total real
2.360000 0.060000 2.420000 ( 2.562157)
1.970000 0.040000 2.010000 ( 2.145008)
1.920000 0.050000 1.970000 ( 2.091060)
1.870000 0.040000 1.910000 ( 2.040251)
1.900000 0.050000 1.950000 ( 2.070622)
1.820000 0.030000 1.850000 ( 1.970871)
1.860000 0.040000 1.900000 ( 2.011723)
1.850000 0.040000 1.890000 ( 2.027080)
2.060000 0.040000 2.100000 ( 2.277219)