From: Wesley J Landaker Date: 2001-06-22T06:55:04+09:00 Subject: [ruby-talk:16728] Fwd: Some quick benchmarks on scripting languages -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello ruby-talk folks! I've been preaching Ruby to a friend of mine at Agilent, and answering lots of questions for him--he's using a lot of stuff with SWIG, and is looking for a good scripting language. Of course, being very practical, he ran some benchmarks. I thought that these would be quite interesting for this list, since I've seen few ruby benchmarks. (Although, using only vectors and hashes isn't actually a very good way to benchmark things--but it's mostly what his applications will be using.) Even more so, because even though Brett was a bit skeptical, it turns out that Ruby even beat C++ in one test. ;) The forwarded message is below (with his e-mail spamified). - ---------- Forwarded Message ---------- Subject: Some quick benchmarks on scripting languages Date: Thu, 21 Jun 2001 15:08:18 -0600 (MDT) From: Brett Williams As you know, Craig and I have been playing around with Python and Ruby. Here are some quick and dirty benchmarks on scripting languages. I used C++ and the STL as a baseline. I also include the code used for each, as I don't pretend to be an expert on any of these languages. I freely admit that the benchmarks are rough, but I think the results are interesting anyway. Real time elaspsed is all that is captured, and includes startup time for each of the interpreters. I do the following operations, each with 1 million elements: Vector append Vector append and then read Vector append and then read with iterators Hash map insert Hash map insert and then read Hash map insert and then read by iterating over the keys The languages covered are C++, Tcl, Perl, Python, and Ruby. Tcl does not have any data for the hash maps as Tcl hashtables are not accessible at the script level (at least as far as I can tell). I also do not know how to do an iteration with Tcl either. All data is in seconds. System: HP Vectra, PIII 733MHz, 128MEG RAM Red Hat Linux 7.1 g++ 2.96 Tcl 8.3.1 Perl 5.6 Python 1.5.2 Ruby 1.6.4 SUMMARY: C++ Tcl Perl Python Ruby v append: .146 8.85 1.33 4.28 1.10 v append and read: .212 14.8 3.04 6.15 2.30 v append and iterate: .159 ---- 2.13 5.21 1.65 h insert: 2.04 ---- 14.4 2.84 3.22 h insert and read: 2.53 ---- 29.8 4.93 4.96 h insert and iterate: 2.62 ---- 69.1 4.78 4.77 As an aside, I also tried 10 million elements in a vector. Of these, only C++ and Ruby were able to complete without running out of memory. It took Ruby 21.9 seconds, and C++ 1.93 seconds to insert 10 million elements and then read them all back (not using iterators). Even more fascinating is that the C++ implementation runs out of memory at 16 million elements. Ruby is able to create a vector of 25 million elements and read the contents back (unless Ruby is lying to me). ***************** VECTOR APPEND ********************* C++: real 0m0.146s #include #include int main() { vector a; for (int i=0; i<1000000; i++) { a.push_back(i); } cout << "finished" << endl; return 0; } Tcl: real 0m8.853s set a {} for { set i 0 } { $i < 1000000 } { incr i 1 } { lappend a $i } puts "finished" Perl: real 0m1.327s for ($i=0; $i<1000000; $i++) { push(@a, $i); } print "finished\n"; Python: real 0m4.280s a = [] for i in range(1000000): a.append(i) print "finished\n" Ruby: real 0m1.102s a = [] for i in 1..1000000 a.push(i) end print "finished\n" ***************** VECTOR APPEND AND READ ***************** C++: real 0m0.212s #include #include int main() { vector a; for (int i=0; i<1000000; i++) { a.push_back(i); } for (int i=0; i<1000000; i++) { int b = a[i]; } cout << "finished" << endl; return 0; } Tcl: real 0m14.829s set a {} for { set i 0 } { $i < 1000000 } { incr i 1 } { lappend a $i } for { set i 0 } { $i < 1000000 } { incr i 1 } { set b {lindex a $i} } puts "finished" Perl: real 0m3.042s for ($i=0; $i<1000000; $i++) { push(@a, $i); } for ($i=0; $i<1000000; $i++) { $b = $a[$i]; } print "finished\n"; Python: real 0m6.154s a = [] for i in range(1000000): a.append(i) for i in range(1000000): b = a[i] print "finished\n" Ruby: real 0m2.304s a = [] for i in 1..1000000 a.push(i) end for i in 1..1000000 b = a[i] end print "finished\n" ***************** VECTOR APPEND AND ITERATE ********************* C++: real 0m0.159s #include #include int main() { vector a; for (int i=0; i<1000000; i++) { a.push_back(i); } vector ::iterator i1, iend1 = a.end(); for (i1 = a.begin(); i1!=iend1; i1++) { int b = *i1; } cout << "finished" << endl; return 0; } Perl: real 0m2.134s for ($i=0; $i<1000000; $i++) { push(@a, $i); } foreach $i (@a) { $b = $i; } print "finished\n"; Python: real 0m5.214s a = [] for i in range(1000000): a.append(i) for i in a: b = i print "finished\n" Ruby: real 0m1.652s a = [] for i in 1..1000000 a.push(i) end for i in a b = i end print "finished\n" ****************** HASH INSERT ******************** C++: real 0m2.043s #include #include struct eqint { bool operator()(int i1, int i2) { return i1==i2; } }; int main() { hash_map< int, int, hash, eqint> a; for (int i=0; i<1000000; i++) { a[i] = i; } cout << "finished" << endl; return 0; } Perl: real 0m14.428s for ($i=0; $i<1000000; $i++) { $a{$i} = $i; } print "finished\n"; Python: real 0m2.835s a = {} for i in range(1000000): a[i] = i print "finished\n" Ruby: a = {} real 0m3.222s for i in 1..1000000 a[i] = i end print "finished\n" ***************** HASH INSERT AND READ ****************** C++: real 0m2.525s #include #include struct eqint { bool operator()(int i1, int i2) { return i1==i2; } }; int main() { hash_map< int, int, hash, eqint> a; for (int i=0; i<1000000; i++) { a[i] = i; } for (int i=0; i<1000000; i++) { int b = a[i]; } cout << "finished" << endl; return 0; } Perl: real 0m29.826s for ($i=0; $i<1000000; $i++) { $a{$i} = $i; } for ($i=0; $i<1000000; $i++) { $b = $a{$i}; } print "finished\n"; Python: real 0m4.925s a = {} for i in range(1000000): a[i] = i for i in range(1000000): b = a[i] print "finished\n" Ruby: real 0m4.956s a = {} for i in 1..1000000 a[i] = i end for i in 1..1000000 b = a[i] end print "finished\n" ******************** HASH INSERT AND ITERATE ********************* C++: real 0m2.619s #include #include struct eqint { bool operator()(int i1, int i2) { return i1==i2; } }; typedef hash_map< int, int, hash, eqint> hashmap; int main() { hashmap a; for (int i=0; i<1000000; i++) { a[i] = i; } hashmap::iterator i1, iend1 = a.end(); for (i1 = a.begin(); i1!=iend1; i1++) { int b = i1->second; } cout << "finished" << endl; return 0; } Perl: real 1m9.124s for ($i=0; $i<1000000; $i++) { $a{$i} = $i; } foreach $key (keys(%a)) { $b = $a{$key}; } print "finished\n"; Python: real 0m4.779s a = {} for i in range(1000000): a[i] = i for i in a.keys(): b = a[i] print "finished\n" Ruby: real 0m4.773s a = {} for i in 1..1000000 a[i] = i end for i in a.keys b = a[i] end print "finished\n" - ---------------------------------------------- | ---------------------- Brett Williams | (970) 288-0475 Agilent Technologies | brettw@ftc.agilent.com - ---------------------------------------------- | ---------------------- - ------------------------------------------------------- - -- Wesley J. Landaker - wjl@mindless.com http://www.landaker.net PGP DSS/DH Key: 0x0F338E07 PGPKey FP: 3AAA 424B B488 198E B68B C0E5 390A BACA 0F33 8E07 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6a (GNU/Linux) Comment: All your base are belong to us. iEYEARECAAYFAjsybS0ACgkQOQq6yg8zjgdUHgCePUEqIsFnY9R7M6JdUiGHFCeD 5xEAoOquXRe6ZJ5MTRGQg7LwN9VXi3S7 =/yfG -----END PGP SIGNATURE-----