Take a peek at Paul's benchmark. Iterate and instantiated 100K empty objects in 10s. That's crazy. You're talking about something that would probably take 1ms in c#. You're talking about a performance deficit four orders of magnitude large.
Regardless, I think you've entirely missed the point. The point is not that the O/RMs generate inefficient queries. They may not be perfection, but for what you're asking of it, by and large the queries are not the issue. We're talking about raw method-dispatch.
This simple benchmark takes about 600ms on my MacBook Air:
require 'benchmark'
puts Benchmark::measure {
i = 0
1_000_000.times { |x| i += x }
}
The same thing takes 1ms in Mono: using System;
using System.Diagnostics;
namespace dispatch {
class MainClass {
public static void Main (string[] args) {
var s = new Stopwatch();
s.Start();
var x = 0;
for (int i = 0; i < 1000000; i++) {
x += i;
}
s.Stop();
Console.WriteLine(s.Elapsed.ToString());
}
}
}
(Forgive me, it's been a very long time since I wrote any c#, but this gave me an excuse to try out Mono. :-) )You could argue that it's not exactly identical code, but it's fairly idiomatic I'd think for each language.
The point is, the sort of performance deficit you carry with Ruby has real consequences. You don't have to dig very deep at all until such concerns are no longer academic. There's financial applications I've worked on in c# doing transaction reporting with 1,000 rows or so per page that would simply put be at a severe handicap under Ruby and it has nothing to do with the RDBMS.
I'm certainly not gonna give Ruby up any time soon. But it's important as a developer to at least be aware of the shape of the box you live in I think.
puts (1 .. 21).inject :*
will output "51090942171709440000". And puts (1 .. 21).inject(:*).class
will output "Bignum" because Ruby switches to big numbers when its integer representation is exceeded.Simple math operations are an admittedly terrible way to demonstrate the point I was trying to make (method dispatch and object instantiation overhead). Dismiss it, accept it, or dig deeper verify it. :-)
using System;
using System.Diagnostics;
namespace testspeed
{
public static class Extensions {
public delegate void Action();
public static void Times (this int numTimes, Action action)
{
for (var i = 0; i < numTimes; i++) {
action ();
}
}
}
class MainClass
{
public static void Main (string[] args)
{
var sw = Stopwatch.StartNew();
var x = 0;
1000000.Times (() => x += 1);
Console.WriteLine ("{0} in {1} ms", x, sw.ElapsedMilliseconds);
Console.ReadKey ();
}
}
}
and it outputs 4 ms. Mono in debug mode on a 3.2 GHz Intel Core i3. For comparison, the parent's ruby code runs in 80ms with Ruby 1.9.2. Big difference, but not quite as bad. I don't know why though?Still, it should take the blink of an eye, not a chin-scratch.
Either way, nice observation. Interesting.
public class dispatch {
public static void main(String args[]) {
long s = System.currentTimeMillis();
int x = 0;
for(int i = 0; i < 1000000; i++)
x += i;
System.out.printf("%d in %d", x, System.currentTimeMillis() - s);
}
}
Just for kicks. I'm not a Java developer but I'd like to get decent at it some day in the near future. Feel free to school me. ;-)