--nextPart82178417.p1r6TaiOAF
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="us-ascii"

Dear list,

some days ago I wrote a script that stored values in an Hashtable with=20=

different buckets. It was some string-parsing grunt work.

I noticed that Ruby became pretty slow when the hashtable grew to ~10 M=
io=20
entries. To make sure it is actually Ruby that is to blame, I wrote com=
parison=20
script snippets in Perl and Python, and yes, Ruby was just plain slower=
.

By reducing the amount of code step-by-step I was able to narrow the pr=
oblem=20
down. Currently, I can reproduce the behaviour with the following simpl=
e=20
scriptlet:

=2D--%<---
tbl =3D { }

10_000_000.times do |i|
  tbl['last'] =3D i*i*i
end
=2D-->%---

Execution times are as follows:

+ ruby loop0r.rb
real    0m10.741s
user    0m10.596s
sys     0m0.107s

+ perl loop0r.pl
real    0m4.503s
user    0m4.420s
sys     0m0.048s

+ python loop0r.py
real    0m6.704s
user    0m6.367s
sys     0m0.274s

Replacing the String I use as Hash key with a symbol, i.e., :last, lowe=
rs the=20
execution time of Ruby dramatically so that it becomes fast than Python=
 (and=20
still slower than Perl, but that's ok).

I was baffled and ran callgrind against the interpreter. It came up wit=
h this:


=2D--%<---
183,248,191  /usr/local/rvm/src/ruby-2.0.0-p247/vm.inc:vm_exec_core'2
155,033,405  /usr/local/rvm/src/ruby-2.0.0-p247/siphash.c:ruby_sip_hash=
24=20
[/home/eveith/.rvm/rubies/ruby-2.0.0-p247/lib/libruby.so.2.0.0]
112,110,714  /usr/local/rvm/src/ruby-2.0.0-p247/insns.def:vm_exec_core'=
2
 93,170,146  /usr/local/rvm/src/ruby-2.0.0-p247/string.c:str_replace=20=

[/home/eveith/.rvm/rubies/ruby-2.0.0-p247/lib/libruby.so.2.0.0]
 78,086,663  /usr/local/rvm/src/ruby-2.0.0-p247/st.c:st_update=20
[/home/eveith/.rvm/rubies/ruby-2.0.0-p247/lib/libruby.so.2.0.0]
 74,991,856  /usr/local/rvm/src/ruby-2.0.0-p247/gc.c:slot_sweep=20
[/home/eveith/.rvm/rubies/ruby-2.0.0-p247/lib/libruby.so.2.0.0]
 73,137,809  /usr/local/rvm/src/ruby-2.0.0-
p247/vm_insnhelper.c:vm_call_cfunc_with_frame'2=20
[/home/eveith/.rvm/rubies/ruby-2.0.0-p247/lib/libruby.so.2.0.0]
 63,043,562  /usr/local/rvm/src/ruby-2.0.0-p247/vm_insnhelper.c:vm_push=
_frame=20
[/home/eveith/.rvm/rubies/ruby-2.0.0-p247/lib/libruby.so.2.0.0]
 61,029,008  /usr/local/rvm/src/ruby-2.0.0-p247/vm.c:rb_yield
=2D-->%---


Now: Why does Ruby call string.c:str_replace? There is obviously no ope=
ration=20
that modifies a string here. In fact, I even use the same String as has=
h key=20
over and over again.

Of course, I can also freeze the String, which amounts to the same as u=
sing a=20
Symbol (performance-wise). Still, I don't understand why Ruby is callin=
g=20
str_*replace*.

What is happening here? And how can I circumvent it?

Thanks alot for any replies!

=09=09=09--- Eric
--nextPart82178417.p1r6TaiOAF
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAABAgAGBQJTQ/VpAAoJEIXD2TZ1epVBbdEP/2awgrhfVyDZ0rEZoFgIYfMw
ASVlksbGhcFP5kerOVOvrSX9gXNXKoead0I+u7qFtAXKfPV5fgA43m49bLErqynj
IaUPgP6QT+VfoEVG2YpDvB4yR2bYYlYh1/L5Zq0ujPXzKitpeE5hzmXHx7JtmiLO
nNclcuKrujTPqJSn9REqXJzyJpkM1Ijs1CXGrfaUIlMuCDVFKaql927k98t/FJQI
yo04J89tZwIzVVnn1ncZnbCwYlpr9OMXXxGYAr/bN5idhtSuptqrteuDLTc99oFU
aXgLyaWEeN4OWjKf0/9rJaaBtpGaYnqCUrcaMi+MrejGKAzqlEMBrmpSmTMJTG4E
cLOotClItsVQwMVpFBgKAC6erYqf0ULew8S64LtAO/KCo6uoMrdvXyXt1k0QZEH+
GNgzwPg+u2HPW1HcIoCB8jUVe/KbXxnsvdMUFG4EXEl4SpZdrfoMSw9k5lp3NpUB
1JH1rCaTLIuihhMC486+Es2XRrHOldPpSrYPgN1xNMvsJ/OcE6+Ji9tLDQ6UNXtI
ym/gSnNsxWOMAumY7VxVEgMz5A6vtK/mcIKYNfxz5GoslGz7CeXXWFQYxC5Sjhzy
V6AvuckWDOR51YSVeXB7QFzN1w8gzElyTZrbqND8py9uivEx0ReqzPJA/nD3oTdM
9kQwwJGJIuN64tHNh1L7
=BPH5
-----END PGP SIGNATURE-----

--nextPart82178417.p1r6TaiOAF--