# For performance, write it in C

**URL:** <https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952>\
**Category:** Ruby\
**Created:** [July 26, 2006, 10:50am UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952 "2006-07-26T10:50:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 10:50am UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/1 "2006-07-26T10:50:11Z")

</div>

Whenever the question of performance comes up with scripting languages  
such as Ruby, Perl or Python there will be people whose response can be  
summarised as “Write it in C”. I am one such person. Some people take  
offence at this and label us trolls or heretics of the true programming  
language (take your pick).

I am assuming here that when people talk about performance they really  
mean speed. Some will disagree but this is what I am talking about.

In this post I want to clear some things up and provide benchmarks as to  
why you should take “Write it in C” seriously. Personally I like to  
write my projects in Ruby or Perl or Python and then convert them to C  
to get a performance boost. How much of a boost? Well here I will give  
you some hard data and source code so that you can see just how much of  
a boost C can give you.

The mini project in question is to generate all the valid Latin squares.  
A Latin square is a grid of numbers (lets say a 9 x 9 grid) that has the  
numbers 1 to 9 appear only once in each row and column. Sudoku grids are  
a subset of Latin squares.

The approach taken is to create a list of all the permutations and then  
build up a grid row by row checking that the newly added row does not  
conflict with any of the previous rows. If the final row can be added  
without problem the solution is printed and the search for the next one  
starts. It is in essence depth first search. The first version of the  
program that I wrote in Perl took 473 minutes to generate all the valid  
5 x 5 Latin squares, version four of the program took 12 minutes and 51  
seconds. The C version of the program took 5.5 seconds to produce  
identical results. All run on the same hardware.

[Latin]$ time ./Latin1.pl 5 \> x5

real 473m45.370s  
user 248m59.752s  
sys 2m54.598s

[Latin]$ time ./Latin4.pl 5 \> x5

real 12m51.178s  
user 12m14.066s  
sys 0m7.101s

[Latin]$ time ./c\_version.sh 5

real 0m5.519s  
user 0m4.585s  
sys 0m0.691s

This is what I mean when I say that coding in C will improve the  
performance of your program. The improvement goes beyond percentages, it  
is in orders of magnitude. I think that the effort is worth it. If a 5 x  
5 grid with 120 permutations took 12 minutes in Perl, how long would a 6

- 6 grid with 720 permutations take? What unit of measure would you be  
using for a 9 x 9 grid?

Size Permutations  
==== ============  
1 1  
2 2  
3 6  
4 24  
5 120  
6 720  
7 5040  
8 40320  
9 362880

Now lets look at first version of the code:

```
 1 #!/usr/bin/perl -w

 2 use strict;
 3 use warnings;

 4 use Algorithm::Permute;

 5 my $width_of_board = shift;

 6 my @permutations;

 7 my $p = new Algorithm::Permute( [1 .. $width_of_board] );

 8 while ( my @res = $p->next ) {
 9 push @permutations, [@res];
10 }
11 my $number_of_permutations = scalar(@permutations);

12 for ( my $x = 0 ; $x < $number_of_permutations ; $x++ ) {
13 add_a_line($x);
14 }

```

Lines 1 to 11 just build up a list of all the permutations using the  
handy Algorithm::Permute module from CPAN. Lines 12 to 14 starts on the  
first row of the solution by trying out all possible permutations for  
the first row.

```
15 sub add_a_line {
16 my @lines = @_;

17 my $size = scalar(@lines);

18 my $ok = 1;
19 for ( my $x = 0 ; $x < $size ; $x++ ) {
20 for ( my $y = 0 ; $y < $size ; $y++ ) {
21 if ( $x != $y ) {
22 $ok = 0 unless compare( $lines[$x], $lines[$y] 

```

);  
23 }  
24 }  
25 }

```
26 if ($ok) {
27 if ( $size == $width_of_board ) {
28 print join(':', map { p($_) } @lines) . "\n";
29 }
30 else {
31 for ( my $x = 0 ; $x < $number_of_permutations ;

```

$x++ ) {  
32 add\_a\_line( @lines, $x );  
33 }  
34 }  
35 }  
36 }

The add\_a\_line() function first checks that none of the lines so far  
conflict (have the same digit in the same column), if it passes and the  
number of lines equals the size of the board then the result is printed  
and another solution is looked for. Failing that another line is added  
and add\_a\_line() is called.

Here is the function that tells if two lines conflict.

```
37 sub compare {
38 my ( $a, $b ) = @_;

39 my $ok = 1;

40 my @aa = @{ $permutations[$a] };
41 my @bb = @{ $permutations[$b] };

42 for ( my $x = 0 ; $x < $width_of_board ; $x++ ) {
43 $ok = 0 if $aa[$x] == $bb[$x];
44 }

45 return $ok == 1;
46 }

```

The p() function is a little utility to convert a list into a string for  
display.

```
47 sub p {
48 my ($x) = @_;

49 my @a = @{ $permutations[$x] };
50 my $y = join( '', @a );

51 return $y;
52 }

```

Well I have just exposed some pretty crap code to eternal ridicule on  
the internet, but there you have it. The code is crap, even non Perl  
programmers will be able to point out the deficenties with this code. It  
works, even though a 5 x 5 grid took 473 minutes to run. Lets try and  
salvage some pride and show version four and see how we managed to speed  
things up.

```
 1 #!/usr/bin/perl -w

 2 use strict;
 3 use warnings;

 4 use Algorithm::Permute;

 5 my $width_of_board = shift;

 6 my @permutations;
 7 my @output;
 8 my %compared;

 9 my $p = new Algorithm::Permute( [1 .. $width_of_board] );

10 while ( my @res = $p->next ) {
11 push @permutations, [@res];
12 push @output, join( '', @res );
13 }
14 my $number_of_permutations = scalar(@permutations);

```

Lines 1 to 14 are doing pretty much what version one was doing except  
that a new list, @output, is being built up to precalculate the output  
strings and remove the need for the p() function. A minor speed up but  
useful.

```
15 for ( my $x = 0 ; $x < $number_of_permutations ; $x++ ) {
16 for ( my $y = 0 ; $y < $number_of_permutations ; $y++ ) {
17 my $ok = 1;

18 my @aa = @{ $permutations[$x] };
19 my @bb = @{ $permutations[$y] };

20 for ( my $z = 0 ; $z < $width_of_board ; $z++ ) {
21 if ( $aa[$z] == $bb[$z] ) {
22 $ok = 0;
23 last;
24 }
25 }

26 if ( $ok == 1 ) {
27 $compared{"$x:$y"} = 1;
28 }
29 }
30 }

```

Lines 15 to 30 introduces new code to precalculate the comparisons and  
feed the results into a hash. Lines 31 to 33 start the work in the same  
way as version one.

```
31 for ( my $x = 0 ; $x < $number_of_permutations ; $x++ ) {
32 add_a_line($x);
33 }

```

And now to the improved add\_a\_line() function. The code has been  
improved to only check that the newly added line does not conflict with  
any of the existsing lines rather than repeatedly comparing the existing  
(valid) lines.

```
34 sub add_a_line {
35 my @lines = @_;

36 my $size = scalar(@lines);

37 my $ok = 1;

38 if ( $size > 1 ) {
39 for ( my $x = 0 ; $x < ( $size - 1 ) ; $x++ ) {
40 unless ( defined $compared{ $lines[$x] .':'.

```

$lines[-1] } ) {  
41 $ok = 0;  
42 last;  
43 }  
44 }  
45 }

```
46 if ($ok) {
47 if ( $size == $width_of_board ) {
48 print join( ':', map { $output[$_] } @lines ) . 

```

“\n”;  
49 }  
50 else {  
51 for ( my $x = 0 ; $x \< $number\_of\_permutations ;  
$x++ ) {  
52 add\_a\_line( @lines, $x );  
53 }  
54 }  
55 }  
56 }

These changes took us down from 473 minutes to just 12. The elimination  
of unnessessary comparisons in add\_a\_line() helped as did the  
precalculation of those comparisons. There are lessons to be learnt  
here, write decent code and cache repetetive comparisons. There are no  
great tricks, just that bad code can cost you dearly and simple things  
can bring big improvements. So with such a massive improvement how could  
we make our code any faster?

Write it in C.

Having learnt the lessons developing the code in Perl I am not going to  
start the whole thing over in C. Using version four I used the  
precalculation phase of the Perl scripts to write out a C header file  
with data structures that would be useful for the C program.

```
 1 #define WIDTH_OF_BOARD 5
 2 #define NUMBER_OF_PERMUTATIONS 120
 3 char *output_strings[] = {
 4 "54321",

```

123 “12345”,  
124 };  
125 bool compared[NUMBER\_OF\_PERMUTATIONS][NUMBER\_OF\_PERMUTATIONS] =  
{  
126 {false, false, …

245 {false, false, …  
246 };  
247 int work[WIDTH\_OF\_BOARD];

This then leaves the C code itself. Lines 1 to 7 includes a load of  
useful stuff, infact it is also probably including some quite  
unneccessary stuff too, I just cut and paste it from another project.

```
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <stdbool.h>
 4 #include <err.h>
 5 #include <string.h>
 6 #include <unistd.h>
 7 #include <sys/types.h>

```

Line 8 is the header file that Perl precalculated.

```
 8 #include "Latin.h"

```

Now the meat. The code is pretty much the same as version four just  
adapted to C. No special C tricks, no weird pointer stuff, an almost  
line for line translation of the Perl code.

```
 9 void
10 add_a_row(int row)
11 {
12 bool is_ok;
13 int x,y;

14 if (row == WIDTH_OF_BOARD) {
15 for (x = 0; x < WIDTH_OF_BOARD; x++) {
16 if (x == 0) {
17 printf("%s", output_strings[work[x]]);
18 } else {
19 printf(":%s", output_strings[work[x]]);
20 }
21 }
22 puts("");
23 } else {
24 for (x = 0; x < NUMBER_OF_PERMUTATIONS; x++) {
25 work[row] = x;

26 is_ok = true;
27 if (row != 0) {
28 for( y = 0; y < row; y++ ) {
29 if(compared[work[row]][work[y]] == false) {
30 is_ok = false;
31 break;
32 }
33 }
34 }
35 if (is_ok == true) {
36 add_a_row(row + 1);
37 }
38 }
39 }
40 }

41 int
42 main(int argc, char *argv[])
43 {
44 add_a_row(0);
45 }

```

And the C version ran in 5.5 seconds. In fact the 5.5 seconds includes  
the Perl program that does all the precalculation to write the Latin.h  
header file, the compiling of the C source and finally the running of  
the program itself. So we have not cheated by doing some work outside  
the timings.

Just think of it, 12 minutes down to 5.5 seconds without having to write  
any incomprehensible C code. Because we all know that C code is  
completely incomprehensible with it doing all that weird pointer stuff  
all the time.

Now the Perl code could be improved, there are tricks that could be  
pulled out of the bag to trim something off the 12 minutes. Perhaps  
another language would be faster? But how far could you close the gap  
from 12 minutes to 5.5 seconds?

Just to up the ante I added -fast -mcpu=7450 to the compiler (gcc  
optimized for speed on an G4 Macintosh) and ran it again.

[Latin]$ time ./c\_version.sh 5 \> x5

real 0m3.986s  
user 0m2.810s  
sys 0m0.540s

Another 30% performance improvement without changing any code.

Lets review the languages we have used and their advantages. C is very  
fast without any stupid tricks. C will give you better control over the  
amount of memory you use (the Perl code eats up massive amounts of  
memory in comparison, the 9 x 9 grid threw an out of memory error on my  
1Gb machine).

It is much easier to develop in Perl. Any error message you get is  
likely to at least give you a clue as to what the problem might be. C  
programmers have to put up with the likes of ‘Bus error’ or  
‘Segmentation fault’, which is why C programmers are grouches. Perl also  
allows you to significantly improve your code without major rewrites.  
There is a module called Memoize that can wrap a function and cache the  
calls all by adding two extra lines to your code, the same is true for  
most scripting languages.

So what am I recommending here, write all your programs in C? No. Write  
all your programs in Perl? No. Write them in your favourite scripting  
language to refine the code and then translate it into C if the  
performance falls short of your requirements. Even if you intend to  
write it in C all along hacking the code in Perl first allows you to  
play with the algorithm without having to worry about memory allocation  
and other such C style house keeping. Good code is good code in any  
language.

If you really really want that performance boost then take the following  
advice very seriously - “Write it in C”.

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 11:02am UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/2 "2006-07-26T11:02:52Z")

</div>

Do you have any preferred tutorials on wrapping Ruby around C libraries?

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 11:23am UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/3 "2006-07-26T11:23:42Z")

</div>

Peter H. schrieb:

> (Example of Perl and C Code)

Peter, is there any chance you could test your program with Ruby Inline?

[http://rubyforge.org/projects/rubyinline](http://rubyforge.org/projects/rubyinline)

I’m on Windows, so I can’t use Ruby Inline (+1 for MinGW btw 🙂

Regards,  
Pit

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 11:48am UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/4 "2006-07-26T11:48:36Z")

</div>

It might be interesting to see how Java fares too - another route  
again.

Pete

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 11:55am UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/5 "2006-07-26T11:55:05Z")

</div>

On 7/26/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Peter H. gave a very good article about prototyping in a scripting  
> language, and then re-coding in c:
> 
> _snip_
> 
> > If you really really want that performance boost then take the following  
> > advice very seriously - “Write it in C”.
> 
> I totally agree that with the current state of the art, this is the  
> right approach.

Sorry, I just couldn’t resist - but maybe you should code Java instead -  
[http://kano.net/javabench/](http://kano.net/javabench/) 😉

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 11:41am UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/6 "2006-07-26T11:41:54Z")

</div>

Peter H. gave a very good article about prototyping in a scripting  
language, and then re-coding in c:

_snip_

> If you really really want that performance boost then take the following  
> advice very seriously - “Write it in C”.

I totally agree that with the current state of the art, this is the  
right approach.

Maybe it doesn’t need saying, but I’m going to… in the vasy majority  
of applications, almost all of their run time is a tiny wee small  
fraction of the code. This is the part that I would write in c (or c++).  
The vast majority of the code (and it’s not there just for fun, it’s  
still completely important to the application) will use a vanishingly  
small fraction of processor time. This is the bit that I would probably  
leave in Ruby.

People talk about the 80:20 principle, but in my experience it’s much  
more like 99:1 for applications. 99% of the code uses 1% of the run  
time. 1% of the code consumes 99% of the run time. That could be the  
signal processing and graphics heavy applications that I have  
experienced though.

Thanks for the comparison, it was great. And thanks for the very nice  
pre-generation of look up tables in perl idea. Nice.

Cheers,  
Benjohn

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 12:13pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/7 "2006-07-26T12:13:26Z")

</div>

On 7/26/06, Tomasz W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > I totally agree that with the current state of the art, this is the  
> > right approach.
> 
> Sorry, I just couldn’t resist - but maybe you should code Java instead -  
> [http://kano.net/javabench/](http://kano.net/javabench/) 😉
> 
> Of course not, but it might be of intereset that there are other  
> programming languages out there  
> Ada, ObjectiveC, Scheme, OCAML, Huskell you name it.  
> That said I agree that one can write code beautifully in C (see GTK for  
> example).  
> I do not think that people are treated bad when they say

“Hmmm, maybe you should know that this kind of performance is not  
possible in Ruby or even slightly faster interpreted languages, and that  
you  
should consider writing part of it in C, it is not so difficult, have a  
look  
here or there”

as opposed to those who write

“Write it in C if you want speed”

That kind of post never gets accepted well and I have the feeling that  
when  
the speed issue comes up there is a certain tendence to reply like that.  
Otoh I agree that the speed issue comes up much too often, but I suggest  
instead of  
replying “Write it in C if you want speed”, one can ignore the post or  
point to older posts.

Just my 0.02â?¬.

Cheers  
Robert

–  
Deux choses sont infinies : l’univers et la bÃªtise humaine ; en ce qui  
concerne l’univers, je n’en ai pas acquis la certitude absolue.

- Albert Einstein

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 1:32pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/8 "2006-07-26T13:32:40Z")

</div>

On Wed, 26 Jul 2006 17:47:13 +0900, Peter H. wrote:

> In this post I want to clear some things up and provide benchmarks as to  
> why you should take “Write it in C” seriously.

This is a great post, and should at least be posted to a blog somewhere  
so  
the masses who don’t know about USENET can still find it on Google!

Jay

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 1:51pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/9 "2006-07-26T13:51:15Z")

</div>

Jay L. wrote:

> Jay

I may well put it in my web site, along with all the source code. Google  
and Yahoo hit it enough.

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 1:47pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/10 "2006-07-26T13:47:53Z")

</div>

Robert D. wrote:

> 

Tact has never been one of my strong points. Your phrasing was much  
nicer I will agree. The things that has been bugging me with this whole  
performance thing is that I am sure that many people do not realise just  
how fast a program written in C can run. The people who seem to take  
offence at being told to write their code in C seem to have no  
significant experience in using C. What also seems to happen is that  
after saying that performance is their number 1 absolute top priority  
they start to back peddle saying how hard C code is to develop. Yes is  
it harder to work with than a scripting language, it is all the rope you  
need to hang yourself with but you can write some blindingly fast code  
if you are prepared to put in the effort. Wasn’t that what they said was  
their number 1 absolute top priority?

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 3:59pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/11 "2006-07-26T15:59:06Z")

</div>

I’ll lob a couple of grenades and then duck for cover.

- Write it in C is as valid as write it in Java (as someone else  
mentioned).  
Java is at least as fast as C for most algorithms. On the JRuby project,  
when we need to clone a C extension or library from Ruby, we typically  
write  
it first in Ruby (to get something running quickly) and then reimplement  
it  
in Java (for performance). The sad truth beyond the numbers and  
quantitative  
comparisons is that a dynamic typed language with no primitives is  
almost  
certainly going to be slower than staticly typed with with  
everything-is-an-object. Toss out your favorite super-fast dyntyped  
language  
if you will…I’m speaking in generalities.
- Write it in C is also as dangerous (in the grand scheme of things) as  
write it in Java, because it has the potential to tie you to a specific  
platform. For better or for worse, there’s a lot of Windows machines out  
there, and practically none of them have compilers. That means anything  
you  
write in C will have to be pre-built for those platforms, or users are  
SOL.  
Java suffers from the same fate…a Java VM is required…but if you’re  
running JRuby you probably have already made that plunge. There’s a  
balance  
to be struck between tying yourself to fast native code or accepting  
slow  
interpreted code. You pay a very specific price either way.

All this said, there’s truth to the idea that we shouldn’t _have_ to  
write  
platform-level code to get reasonable performance, and every effort  
should  
be made to improve the speed of Ruby code as near as possible to that of  
the  
underlying platform code. On JRuby, we are working on various compiler  
designs to turn Ruby code directly into Java bytecodes and methods,  
cutting  
out the overhead of node-by-node interpretation. Early returns show as  
high  
as 65% gains for some algorithms. We’re also looking at modifications to  
the  
parsing process to structure the AST in ways that makes it easier to  
interpret. We in particular have to compete with a vast world of Java  
code  
and Java coders, and although we’ll never match the performance of raw  
Java  
we endeavor to get as close as possible.

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 4:05pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/12 "2006-07-26T16:05:18Z")

</div>

On Jul 26, 2006, at 8:57 AM, Charles O Nutter wrote:

> - Write it in C is as valid as write it in Java (as someone else  
> mentioned).  
> Java is at least as fast as C for most algorithms.

I’m Java Certified and I’ve been hearing people say this for years,  
but I just haven’t experienced this myself. You guys must develop on  
much faster boxes than my MacBook Pro. 😉

James Edward G. II

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 4:14pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/13 "2006-07-26T16:14:44Z")

</div>

Charles O Nutter wrote:

> I’ll lob a couple of grenades and then duck for cover.
> 
> - Write it in C is as valid as write it in Java (as someone else  
> mentioned).  
> Java is at least as fast as C for most algorithms.

As someone who is paid to program in Java I very seriously doubt this.  
However I will write a Java version of the code and time it. It should  
be interesting to say the least.

> All this said, there’s truth to the idea that we shouldn’t _have_ to  
> write  
> platform-level code to get reasonable performance, and every effort  
> should  
> be made to improve the speed of Ruby code as near as possible to that  
> of the  
> underlying platform code.  
> We are talking about two different things here. I was talking about  
> performance as being the number 1 absolute top priority, you are talking  
> about ‘reasonable performance’. As far as I am concerned for those  
> scripts that I don’t convert to C Perl, Ruby and Python are fast enough.  
> Other people think that they are not, they seem to expect the sort of  
> performance C gives when they write things in a scripting language. I  
> think that they are barking.

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 2:28pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/14 "2006-07-26T14:28:17Z")

</div>

On 7/26/06, Peter H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Jay L. wrote:
> 
> > On Wed, 26 Jul 2006 17:47:13 +0900, Peter H. wrote:
> > 
> > > In this post I want to clear some things up and provide benchmarks as to  
> > > why you should take “Write it in C” seriously.

Something else to consider is the ease with which Ruby extensions can  
be written in C. The first time I tried I has something running in 20  
minutes.

Though if I was going to choose a (single) language for raw  
performance I’d try to go with Pascal or Ada.

Les

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 4:21pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/15 "2006-07-26T16:21:21Z")

</div>

Hi Peter!

> Whenever the question of performance comes up with scripting  
> languages  
> such as Ruby, Perl or Python there will be people whose  
> response can be  
> summarised as “Write it in C”. I am one such person. Some people take  
> offence at this and label us trolls or heretics of the true  
> programming  
> language (take your pick).

The last (and only) time I called someone a troll for saying  
‘Write it C’ it was in response to a rails related question.  
Further the OP asked for configuration items and such, but maybe  
that’s a whole other storry. (and of course you can write  
C Extensions for rails… yeah, yadda, yadda 🙂 )

…snip 52 lines Perl, some hundred lines C …

> sys 0m7.101s
> 
> [Latin]$ time ./c\_version.sh 5
> 
> real 0m5.519s  
> user 0m4.585s  
> sys 0m0.691s

## Just to show the beauty of ruby:

require ‘rubygems’  
require ‘permutation’  
require ‘set’

$size = (ARGV.shift || 5).to\_i

$perms = Permutation.new($size).map{|p| p.value}  
$out = $perms.map{|p| p.map{|v| v+1}.join}  
$filter = $perms.map do |p|  
s = SortedSet.new  
$perms.each\_with\_index do |o, i|  
o.each\_with\_index {|v, j| s.add(i) if p[j] == v}  
end && s.to\_a  
end

$latins = []  
def search lines, possibs  
return $latins \<\< lines if lines.size == $size  
possibs.each do |p|  
search lines + [p], (possibs -  
$filter[p]).subtract(lines.last.to\_i…p)  
end  
end

search [], SortedSet[\*(0…$perms.size)]

## $latins.each do |latin| $perms.each do |perm| perm.each{|p| puts $out[latin[p]]} puts end end

(does someone has a nicer/even faster version?)

would you please run that on your machine?  
perhaps you have to do a “gem install permutation”  
(no I don’t think it’s faster than your C code, but  
it should beat the perl version)

> If you really really want that performance boost then take  
> the following  
> advice very seriously - “Write it in C”.

Agreed, 100%, for those who want speed, speed and nothing  
else there is hardly a better way.

thanks

Simon

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 4:23pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/16 "2006-07-26T16:23:51Z")

</div>

Peter H. wrote:

> We are talking about two different things here. I was talking about  
> performance as being the number 1 absolute top priority, you are talking  
> about ‘reasonable performance’. As far as I am concerned for those  
> scripts that I don’t convert to C Perl, Ruby and Python are fast enough.  
> Other people think that they are not, they seem to expect the sort of  
> performance C gives when they write things in a scripting language. I  
> think that they are barking.

I quite agree with this. To Nutter’s point, one can make one’s own  
choice between C and Java once the decision has been made to write  
platform-level code. But most code, perhaps nearly all code, should stay  
in dyntyped script, in order to optimize the development/runtime  
cost-balance. I think you can get tremendous benefits from factoring  
code cleverly enough to keep the native-code components as small as  
possible. And this is often a nontrivial exercise because it depends on  
a good understanding of where performance costs come from in any  
particular program.

To the point about Java: as I mentioned upthread, working-set size is  
often the key limiting factor in Ruby performance. On a large and busy  
server (which is my target environment most of the time), Java can be a  
very inappropriate choice for the same reason!

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 4:21pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/17 "2006-07-26T16:21:33Z")

</div>

On 7/26/06, James Edward G. II [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Jul 26, 2006, at 8:57 AM, Charles O Nutter wrote:
> 
> > - Write it in C is as valid as write it in Java (as someone else  
> > mentioned).  
> > Java is at least as fast as C for most algorithms.
> 
> I’m Java Certified and I’ve been hearing people say this for years,  
> but I just haven’t experienced this myself. You guys must develop on  
> much faster boxes than my MacBook Pro. 😉

Well la-dee-dah! Seriously though, there’s a volume of tests and  
benchmarks  
(for what they’re worth) that show this to be true, and for  
memory-intensive  
situations Java almost always wins because lazy memory management allows  
work to get done first, faster. Granted, Java’s abstractions make it  
easier  
to write bad code…but that’s true of every language, including C.

- Charles Oliver N., CERTIFIED Java Developer

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 4:27pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/18 "2006-07-26T16:27:59Z")

</div>

On 7/26/06, Peter H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> be interesting to say the least.  
> Doubt all you like.

> scripts that I don’t convert to C Perl, Ruby and Python are fast enough.  
> Other people think that they are not, they seem to expect the sort of  
> performance C gives when they write things in a scripting language. I  
> think that they are barking.

They may be hoping for the impossible, but that doesn’t mean they  
shouldn’t  
hope and that doesn’t mean they shouldn’t be frustrated when the stock  
answer is “write it in C”. The fact that Ruby and other dynamic  
languages  
are not as fast as compiled C is not the language’s fault or the user’s  
fault…it’s an implementation flaw. It certainly may be a flaw that  
can’t  
be fixed, a problem impossible to solve, but there’s nothing about a  
language’s design that should necessitate it being slower than any other  
language. Perhaps we haven’t found the right way to implement these  
languages, or perhaps some of us have and others just aren’t there yet.  
Either way, it’s not the language that’s eventually the problem…it’s  
simply the distance from what the underlying platform wants to run  
that’s an  
issue. C is, as they put it, closer to “bare metal”, but only because C  
is  
little more than a set of macros on top of assembly code. If the  
underlying  
processor ran YARV bytecodes, I doubt Ruby performance would be a  
concern.

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 4:31pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/19 "2006-07-26T16:31:22Z")

</div>

Charles O Nutter wrote:

> - Charles Oliver N., CERTIFIED Java Developer

I dont doubt for simple applications and algorithms java is nearly as  
fast as C if not equivalent. Though for larger java projects such as  
Eclipse, i’ve had a horrible time of it being slow and cumbersome on the  
system, and Visual Studio will run fine and be far more responsive.  
I dont really know why that is it could be as simple as some bad code in  
the java gui layer that Eclipse is using.

---

<div class="post-metadata">

**Author:** ![tekhne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/90ced4/32.png) [@tekhne](https://www.ruby-forum.com/u/tekhne)\
**Post date:** [July 26, 2006, 4:44pm UTC](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952/20 "2006-07-26T16:44:58Z")

</div>

On 7/26/06, Jay L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Wed, 26 Jul 2006 17:47:13 +0900, Peter H. wrote:
> 
> > In this post I want to clear some things up and provide benchmarks as to  
> > why you should take “Write it in C” seriously.
> 
> This is a great post, and should at least be posted to a blog somewhere so  
> the masses who don’t know about USENET can still find it on Google!

well, I didn’t post the original post (though I did link to it). I  
did post my take  
on it. At it’s core: write it in Ruby and if it’s too slow, profile  
it and rewrite the  
slow parts (in C if need be). Rewriting the whole app in C when Ruby  
makes  
cohabitating with C (or C++ or Objective C) so easy just seems  
pointless.

My post is at

> **[RubyInline, Making Making Things Faster Easier](http://on-ruby.blogspot.com/2006/07/rubyinline-making-making-things-faster.html)**
>
> Today on ruby-talk, I caught a thread called "For Performance, Write it in C" . I'd like to present a slight amendment to that thesis. Le...

[Next page](https://www.ruby-forum.com/t/for-performance-write-it-in-c/99952.md?page=2)
