Archive for July, 2010

Benchmarking simple stuff in different languages

Posted in linux, perl, programming on July 29, 2010 by skeldoy

I wanted to find out just how big the differences in speed was between popular languages. To benchmark the languages I choose a very simple but common operation to be performed in similar conditions with different languages. The results came as quite a surprise.

Method

To do this benchmark I made simple Hello World programs in the different languages (some compiled, some interpreted). I then wrote a simple wrapper in Perl that ran the programs in a for-loop, simulating running the program 1000 times. This method may be a testament to how well my ubuntu fires different executables and frameworks and not to the code, but it is still interesting to see how a real world application of a program language is to do a menial task like printing a string many times. To eliminate the graphics-card I piped the output of the programs to a file in one instance and did nothing with it in another instance (just back-ticking the output to a perl-variable and then doing nothing to it). Before claiming that the methodology is unfair I would like to point out that this is the way I run programs on linux/unix and that for my particular use this is  a valid benchmark.

Language Seconds
Asm (nasm) 0.46
C (llvm) 0.84
Obj-C (llvm) 0.85
C (gcc) 0.87
Sh 1.11
C++ (llvm) 1.22
Pascal (fp) 1.48
Awk 1.83
C++ (gcc) 1.86
Fortran (G95) 2.15
Brainfuck 2.24
Perl 3.01
Bash 3.13
Cobol (open) 3.35
Obfuscated Perl 3.68
Ruby 5.35
Tcl 5.53
Python 16.33
Php 103.97
Java 121.88
Groovy 1318

Doing another benchmark where I basically let the hello world program contain a 1000000 long for-loop written in the program itself and then running this program 10 times I got different results:

GCC:    timethis 10:  1 wallclock secs ( 0.00 usr  0.00 sys +  0.69 cusr  0.39 csys =  1.08 CPU) @  9.26/s (n=10)
LLVM:    timethis 10:  1 wallclock secs ( 0.00 usr  0.00 sys +  0.68 cusr  0.42 csys =  1.10 CPU) @  9.09/s (n=10)
Perl:    timethis 10:  2 wallclock secs ( 0.00 usr  0.00 sys +  1.73 cusr  0.44 csys =  2.17 CPU) @  4.61/s (n=10)
Python:    timethis 10:  8 wallclock secs ( 0.00 usr  0.00 sys +  6.41 cusr  0.68 csys =  7.09 CPU) @  1.41/s (n=10)
Php:    timethis 10: 40 wallclock secs ( 0.00 usr  0.00 sys +  7.20 cusr 28.15 csys = 35.35 CPU) @  0.28/s (n=10)
Java:    timethis 10: 111 wallclock secs ( 0.00 usr  0.01 sys + 36.21 cusr 61.36 csys = 97.58 CPU) @  0.10/s (n=10)
Bash:    timethis 10: 321 wallclock secs ( 0.00 usr  0.01 sys + 248.54 cusr 49.48 csys = 298.03 CPU) @  0.03/s (n=10)

This speaks to the sluggishness of the different interpreters and virtual machines and/or the size of the executable. But it also underlines the importance of choosing which programming language you use wisely depending on the case you want to solve. Sure this is a moot point in most cases, but imaging taking development time into account. Writing something in PHP can be OK to solve a problem quickly, but seeing that writing the same code in Perl can be as easy or even easier and seeing the performance boost that script would have makes you wonder why PHP is even out there.

The most surprising result is the Bash. Running a simple bash-script 1000 times from the console is pretty snappy in terms of other scripting languages, but having bash loop a million times and running that is slower than even Java. That is a real surprise. The relative slowness of Python is also interesting, given that Python’s popularity is growing where Perl looses supporters. But equally as surprising is the speed at which Perl does this simple operation. Writing stuff in Perl is relatively straight forward (compared to C) but that does not seem to be a problem when doing menial tasks like this.

Language Seconds
Asm (nasm) 0.46
C (llvm) 0.84
Obj-C (llvm) 0.85
C (gcc) 0.87
Sh 1.11
C++ (llvm) 1.22
Pascal (fp) 1.48
Awk 1.83
C++ (gcc) 1.86
Fortran (G95) 2.15
Brainfuck 2.24
Perl 3.01
Bash 3.13
Cobol (open) 3.35
Obfuscated Perl 3.68
Ruby 5.35
Tcl 5.53
Python 16.33
Php 103.97
Java 121.88
Groovy 1318

Converting images between formats

Posted in linux, macosx, perl on July 20, 2010 by skeldoy

I wanted to convert a bitmap (.bmp) image to an ascii art here the other day.

I did ls /usr/bin/*toascii and found a program to convert from pbm to ascii (pbmtoascii) from the netpbm package. That was swell. So I did another ls /usr/bin/*topbm to find a way of doing a .pbm image. I got a list of programs but alas no bmptopbm.

So after contemplating usage of the many online ascii art generators I decided to do the least cost effective thing and write a program to determine possible conversion paths from one format to another using the netpbm and other packages out there.

I tried writing a recursive function that looked for converters until all of them would be found, but due to the nature of the netpbm-package some image-formats are only convertible to one other format and some are convertible to multiple formats. That meant that I have a lot pitfalls in terms of writing a good recursive function to find all of them. Multiple loops to get stuck in. So I gave the job to my CPU and decided to not spend my time scratching my head for a recursive routine. In stead I would map out all the converters in a couple of layers in both directions and use Dijkstra or some other graph-traversing algorithm to find the way to go.

#!/usr/bin/perl
use Graph;
my $g = Graph->new;
$input = $ARGV[0];
$output = $ARGV[1];
$g->add_vertex($input);
$g->add_vertex($output);
my @toOutput = &findTo($output);
foreach my $format ( @toOutput) {
$g->add_vertex($format);
$g->add_path($format,$output);
my @levelTwo = &findTo($format);
foreach my $forma (@levelTwo) {
$g->add_vertex($forma);
$g->add_path($forma,$format);

and so on and so forth. And thus be able to do:

print “Graph: $g \n”;
@path = $g->SP_Dijkstra($input,$output); if (!@path) { print “No path\n”; }
else { print “Dijkstra-Path: @path \n”; }

And that would yield, when running for instance find bmp ascii:

Dijkstra-Path: bmp ppm pgm pbm ascii

And thus I found a way of converting a .bmp to a .ppm and convert the .ppm to a .pgm to be converted to a .pbm and lastly from .pbm to .ascii. Adding a couple of lines to map the graph point that is the mighty ImageMagick convert tool I can then convert from jpeg to ascii doing the extra step from jpeg to bmp.

So if anybody wonders … for instance how to convert a .st4-file to .tiff here’s the solution:
st4 to pgm, pgm to pbm, pbm to gem, gem to pnm, pnm to tiff…

Or maybe you are wondering how to convert a PostScript file to ascii in a completely useless way? :
ps to pnm, pnm to jpeg, jpeg to bmp, bmp to ppm, ppm to pgm, pgm to pbm, pbm to ascii

Follow

Get every new post delivered to your Inbox.