Archive for July, 2008

Hello planet-web

Tuesday, July 15th, 2008

It seems I am now on planet gnome. Thanks Jeff! I’d better introduce myself. I am a 4th year CS student living in Cape Town, South Africa. I have been hacking on Glade 3 since 2006, and have committed bug fixes to various GNOME modules.

Since November, I have been working on a new project of mine, Panda, a Smalltalk system. Its a personal mastery project, aimed at improving my programming skills whilst producing a complex system. I didn’t think I was challenging myself with glade3, and realised that I no longer wanted to do application development using C and GObject. I was on the lookout for a new language, sampling Java, Ruby, and Objective-C. I finally made my bed with Smalltalk.

My long term goal is put a GNOME development environment on top of Panda. Smalltalk IDEs are very different to conventional ones such as Eclipse or Emacs. For one, there is no process boundary separating the IDE and the program being tested, allowing all sorts of rich refactoring and inspection. Gilad Bracha speaks more about this.

That’s going to be at least 18 months away though, since there’s still a lot of VM work to be done. We do have some pretty compelling VM technology in panda right now, including a bytecode interpreter, compacting garbage collector, and fast tagged integers. Of course this all normal stuff for most Smalltalk VMs out there. The next step for me is rewrite the compiler in Smalltalk, since the VM seems stable enough to support it.

Fibonacci Redux

Tuesday, July 15th, 2008

Time for more microbenchmarks! Someone just pointed me out to this post which describes another fibonacci shootout. It gave the brand new Ruby 1.9 VM a test drive. Ruby 1.9′s execution model is quite different from 1.8, featuring a highly optimized bytecode interpreter (codenamed YARV). I must admit that I totally overlooked YARV. All the buzz around Rubinius distracted me.

YARV beats the pants off ruby 1.8. It also outperforms Panda Smalltalk, not by much though. I have prepared a fresh benchmark. This time I present the fibonacci code using images since wordpress refuses to let me format language code sanely. I also got a bit carried away with GIMP and made the code look all pretty.

fib-rb190.png

fib-st2.png

Progress

Thursday, July 10th, 2008

I am having great fun working on my Smalltalk VM. I spent the last few weeks mainly on implementing a compacting garbage collector. There have been some nice additions to the class library, including the Set, Dictionary, and System classes.What’s been particularly pleasing to me personally is that certain benchmarks have come out very fast, faster than Python or Ruby.

Fibonacci Benchmark

fibonacci
    self <= 2
        ifTrue: [^ 1]
        ifFalse: [^ (self - 2) fibonacci + (self - 1) fibonacci].

The naive recursive fibonacci function isn’t a very exemplary benchmark. Nevertheless, I am advertising the results here because I think its a good start. In my opinion, the fibonacci function does at least give a good benchmark for method invocation performance (i.e changing the current context or activation record of an interpreter). The benchmarks below are all based on calculating the 32nd fibonacci number. I assume that the Python and Ruby binaries are compiled using the optimal CFLAGS. If that’s not the case, then I guess Ubuntu has a bit of a problem.

Squeak Smalltalk: 0.427s

The winner, Squeak. I can’t reason about why its faster than Panda. I suspect squeak’s context management scheme is slightly more optimized at the moment.

Panda Smalltalk: 0.67s

Yes, that’s my VM! coming a respectable second. As I stated above, there’s still work to be done on context management. The executable was compiled using “-g -O3 -fomit-frame-pointer”.

Python: 1.18s

Python has a bytecode interpreter and uses the C stack to store activation records. So its context management is probably an order of magnitude faster than Panda. I suspect the python is slower as it allocates an actual object for each integer. In Panda, integers are just stuffed into pointers, which are then tagged in the two low-order bits so that the interpreter can differentiate between normal objects and integers.

Ruby: 4m0.2s

No excuse. This gives dynamic languages a bad name. I suspect the main performance killer here is that Ruby’s execution model is based upon an abstract syntax tree rather than bytecodes. The problem with AST’s is that the nodes are spread throughout the heap, reducing locality. A lot of indirect memory references are required during execution, which slows things down. Hopefully Rubinius or JRuby will improve matters since they include bytecode interpreters.