Archive for May, 2007

links for 2007-05-30

The battle of the languages part II

My previous post about a programming contest I had with my friends was wildly popular. Much much more than I even thought possible.

I started with a simple comparison of PHP, C, Ruby, Erlang and Javascript and ended up with lots of comments where people posted interesting implementations in more and more languages, even obscure ones (to me) like Haskell and Ocaml.

I owe everyone a fairer benchmark so I will do the test again, this time testing the following languages:

  • C
  • Common Lisp
  • Erlang
  • Haskell
  • Javascript
  • Java
  • Ocaml
  • Perl
  • PHP
  • Python
  • Ruby

I need submissions for most of these languages, and I actually am quite open to submissions for the languages I speak :)

The rules are simple, the program has to store the results in an array (not just count them) and has to run without any strange libraries or compilers or compiler switches. To avoid interpreter starting time problems, please submit programs that autotime themselves.

As usual we’ll find the pythagorean triplets up to 5000. The reference implementation is the following, in Ruby:

t = Time.now
result = []
2.upto(5000) do |c| 
  1.upto(c-1) do |b|
    a = Math.sqrt(c*c - b*b)
    result << [a.to_i, b, c] if a.to_i == a 
  end
end
puts Time.now - t

This code takes 15.70s to run on my macbook pro.

Now it’s your turn!

Update: Lua version by Sindisil

local tt = os.clock()
local result = {}
local c
  for c = 2, 5000 do
    local b
    for b = 1, c-1 do
      local a = math.sqrt(c*c - b*b)
      if a == math.floor(a) then
      result[#result+1] = { a, b, c }
    end
  end
end
print(os.clock() - tt)

It takes 5.48s to run on my box.

Update: new Ruby version.

include Math
 
a, b, c = 0
result = []
2.upto(5000) do |c| 
  d = c * c
  1.upto(c-1) do |b|
    a = sqrt(d - b*b)
    result << [a.floor, b, c] if a.floor == a 
  end
end
puts Process.times[0]

Following Gabriele Renzi’s suggestions we now have a faster ruby version: 12.30s

Update: faster Lua version from Chris Swetenham, it runs in 3.44s

local tt = os.clock()
local result = {}
local c
local n = 1
local math = math
local sqrt = math.sqrt
local floor = math.floor
 
for c = 2, 5000 do
  local b
  for b = 1, c-1 do
    local a = sqrt(c*c - b*b)
    if a == floor(a) then
      result[n] = { a, b, c }
      n = n + 1
    end
  end
end
 
print(os.clock() - tt)

Update: PHP version by Fullo

<?php
$start = microtime(true);
$a = $b = $c = 0;
$result = array();
 
for ($c = 2; $c <= 5000; $c++) {
  for ($b = 1; $b < $c; $b++) {
    $a = sqrt($c*$c - $b*$b);
	if (intval($a) == $a) 
       $result[] = array($a,$b,$c);              
  }
}
echo (microtime(true) - $start);
?>

It runs in 9.73s.

Update: Python version from ludo, it runs in 11.2s

from time import clock
 
start = clock()
 
from math import sqrt
 
results = []
 
for c in xrange(2, 5001):
  d = c * c
  for b in xrange(1, c):
    a = sqrt(d - b * b)
    if a % 1 == 0.0:
      results.append((a, b, c))
 
print clock() - start

The results for now:

  1. Lua 3.44
  2. PHP 9.73
  3. Python 11.20
  4. Ruby 12.30

links for 2007-05-22

Xen and the Art of Rails Deployment

Ezra Zygmuntowicz is one of the few recognized masters of Rails deployment. In his talk at RailsConf2007 he pointed out some deployment strategies and some common errors programmers do.

Being a great guy he posted the slides on his blog.

I recommend to go and check them out asap, I did, and I feel a better person now :)

links for 2007-05-21

Guy Kawasaki is a Wise Man

It may sound obvious, but he truly is. I was reading this response he made to a post that criticised his newest product, truemors, and the last paragraph really struck me:

Here’s what I truly don’t understand. Sure, shoot me and Truemors down. It’s okay. I’m a big boy and a juicy target. Such is life. But if I were an entrepreneur, I would be thinking: “Life is good. Guy has shown that with $12,000 and seven weeks of work you can launch a company today. Open source has changed the world. Now I don’t need to spend 6-9 months sucking up to clueless VCs in between their golf games and trips to the south of France and 6-9 months duking it out with a compiler. By tapping the blogosphere I can get PR without spending $10,000/month on a PR firm and $40,000 at Demo. I can come up with an idea, launch it, and see if it works.”

Boy, is he right.

Transaction in Rails

In an application I wrote for a client I needed transactions to handle a batch import of records from a legacy table into different models.

I browsed the documentation, googled for info and even asked in #rubyonrails, but wasn’t able to get any help, so I had to resort to good old trial and error.

First I tried nested transactions (the old way):

FirstModel.transaction do 
  SecondModel.transaction do
    ThirdModel.transaction do
      FourthModel.transaction do
        fourth.do_stuff
        third.save
        second.handle_your_stuff
        first.good_old_foo_bar
      end
    end
  end
end

I had a couple of problems with this code:

  • Ugly
  • Deprecated

It also didn’t seem to work for me, so I banged my head against my laptop for half a hour or so and suddenly the rails documentation started to make sense, so I wrote this code instead:

transaction do
  first.save!
  second.save!
  third.save!
  fourth.save!
end

The reason I used save! was that the documentation says that a transaction block catches exceptions. Unfortunately that’s not true and to make it work I had to remove the exclamation marks.

Now I had another problem. I included the transaction code in a class I put in lib/, ImportJob, and I was using it with script/runner:

script/runner 'ImportJob.run' -e ENVIRONMENT

All of a sudden I started getting method missing errors on transaction. Now I could investigate and do the right thing or just hack a solution – I decided to hack a solution :)

class ImportJob < ActiveRecord::Migration
end

Deriving ImportJob from Migration solved my problems. Now if anyone has a cleaner solution I will be happy to implement it but at least I solved my problem with transactions (and I hope this will be helpful for someone else too).

Update: Tim pointed out some flaws in my code and some more testing revealed that I needed to have an exception to trigger a Rollback, so I modified the block:

begin
  transaction do
    first.save!
    second.save!
    third.save!
    fourth.save!
  end
rescue ActiveRecord::RecordInvalid => invalid
  # do whatever you wish to warn the user, or log something
end

This works fine, thanks Tim!

Hack Day Badge

As you probably know I’m going to the Hack Day in June. That means I’m entitled to use one of these badges.

Go me! :)