gonium.net » performance http://gonium.net/md so much time, so little to do. Sat, 11 Sep 2010 16:42:09 +0000 en hourly 1 http://wordpress.org/?v=3.0.1 Ruby 1.9 Performance http://gonium.net/md/2009/04/17/ruby-19-performance/ http://gonium.net/md/2009/04/17/ruby-19-performance/#comments Fri, 17 Apr 2009 09:51:15 +0000 md http://gonium.net/md/?p=146 I’m currently using Ruby to optimize schedules based on a simulated annealing approach. For my current intermediate version I rely on marshalling internal datastructures really frequently. Out of curiosity I compared the runtimes of Ruby 1.8 and 1.9:

  • Ruby 1.8.6: 21 minutes, 55 seconds
  • Ruby 1.9.0: 22 minutes, 13 seconds

I certainly did not expect any wonders, but in theis case, the runtimes are about the same. So I’m investigating further, using the ruby 1.8 profiler on a smaller test problem:


% cumulative self self total
time seconds seconds calls ms/call ms/call name
33.20 32.96 32.96 661 49.86 77.25 Marshal.load
17.80 50.63 17.67 6365 2.78 14.96 Array#each
17.52 68.03 17.40 601659 0.03 0.03 IO#getc
9.19 77.15 9.12 660 13.82 13.82 Marshal.dump
6.01 83.12 5.97 187158 0.03 0.03 Float#+

My code spends 42.39 percent of its runtime doing marshalling operations. For Ruby 1.9, the code spends 48.98 percent of its runtime doing marshalling. This is somewhat disappointing. In a second round I changed my code to not relying on marshalling – basically, I am using clone on essential internal datastructures. All other information can be reconstructed afterwards. This means that I need to recompute certain values, but evidently this is a much faster approach:

  • Ruby 1.8.6: 1 minute, 34 seconds
  • Ruby 1.9.0: 1 minute, 17 seconds

Note to self: always use a profiler before refactoring code for performance reasons.

]]>
http://gonium.net/md/2009/04/17/ruby-19-performance/feed/ 0
Code Kata: Project Euler #1 http://gonium.net/md/2008/03/30/code-kata-project-euler-1/ http://gonium.net/md/2008/03/30/code-kata-project-euler-1/#comments Sun, 30 Mar 2008 18:13:39 +0000 md http://gonium.net/md/2008/03/30/code-kata-project-euler-1/ code katas, I spend my sunday morning thinking about integer performance in C++. Project Euler provides a nice collection of mathematical problems. As it turns out, some of my assumptions on C++ were totally wrong :-) The problem to solve is the following:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.
Quite easy. A straightforward, naive implementation uses the modulo operator to filter the integers up to the maximum: unsigned long method1(const unsigned long max) { unsigned long sum=0; for (unsigned long i=0; i torrent; for (unsigned long i=0; i::iterator it; for (it=torrent.begin(); it != torrent.end(); it++) { sum += (*it); } return sum; } Turns out this code is way slower than the first method: 0.34318700 seconds, more than two orders of magnitudes. Thinking of it, it is easy to see why: while the first method can completely run within the CPU, the second code suffers from accessing the main memory. I didn’t assess the overhead imposed by the std::set (no working gprof around). As it turns out, the C++ modulo operator uses the assembler div operation – so the compiler can optimize the code, keep all variables in registers, and use a fast operation. However, the above code is not quite nice as it allows integer overflows for the sum variable. The GNU MP Bignum Library (GMP) provides big integers. Method 3 uses them for the sum variable: mpz_class method3(const unsigned long max) { mpz_class sum(0); for (unsigned long i=0; i Project Euler – Problem 1 Method 1: 1404932684 -> 0.00952700 s. Method 2: 1404932684 -> 0.34736500 s. Method 3: 1404932684 -> 0.01851300 s. Method 4: 1404932684 -> 0.57744300 s. Method 5: 1404932684 -> 0.00094000 s. Creating comparison of methods 4 and 5 100 2318(0.00006400) 2318(0.00001400) 10000 23331668(0.00579500) 23331668(0.00043900) 1000000 233333166668(0.57718100) 233333166668(0.05124100) 100000000 2333333316666668(57.69583200) 2333333316666668(5.84172500) You can download the code from the download page.]]>
http://gonium.net/md/2008/03/30/code-kata-project-euler-1/feed/ 0