For performance, write it in C

E

Edgardo Hames

Yes, it is. It's a set of libraries and executables that emulate a
Windows environment.

The name 'Wine' derives from the recursive acronym "Wine Is Not an
Emulator" (rather, it implements a compatibility layer), although some
have used the unofficial expansion "Windows Emulator" [0]

As Wine's name says: "Wine Is Not an Emulator" [1]

Wine is an Open Source implementation of the Windows API on top of X
and Unix. Think of Wine as a compatibility layer for running Windows
programs [2]

[0] http://en.wikipedia.org/wiki/Wine_(software)
[1] http://www.winehq.com/site/myths
[2] http://www.winehq.com/

Peace,
Ed
--=20
Encontr=E1 a "Tu psic=F3pata favorito" http://tuxmaniac.blogspot.com

Thou shalt study thy libraries and strive not to reinvent them without caus=
e,
that thy code may be short and readable and thy days pleasant and productiv=
e.
-- Seventh commandment for C programmers

I have made this letter longer than usual because I lack the time to
make it shorter.
-- Blaise Pascal
 
S

Schüle Daniel

Peter said:
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.

write in VHDL (or Verilog or SystemC), synthesize you piece of
hardware, plugin into PCI, have fun with most performant (in terms of
speed)and efficient (in terms of energy consumption) solution
:)

[...]
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.

I like C, but in this context C can be replaced with any compiled language.
If you really really want that performance boost then take the following
advice very seriously - "Write it in C".

from my point of view C has the only advantage of running on nearly
every platform. As I said above any of compiled languages would speed up
the code.

my 2 cents
Regards, Daniel
 
K

Keith Gaughan

Yes, it is. It's a set of libraries and executables that emulate a
Windows environment.

The name 'Wine' derives from the recursive acronym "Wine Is Not an
Emulator" (rather, it implements a compatibility layer), although some
have used the unofficial expansion "Windows Emulator" [0]

Just lie GNU's Not Unix, LAME Ain't an MP3 Encoder, and so on. :)

Seriously though, compatibility layers *are* emulators, what they're not
is *full hardware* emulators. Unfortunately, when people think of
emulators, they think of the likes of Vice, DOSBox, Stella, MAME, &c. So
to avoid the misconception that they're full hardware emulators, projects
like Wine avoid the label. But in the strict sense, a compatibility layer
*is* an operating system emulator because they trick the software
running on top of them into thinking they exist in a different
environment than they really are: it emulates Windows, not the machine
running it.

K.
 
K

Keith Gaughan

Chad, do you mind if we take this off list? There's no sense in either
of us cluttering up the list with an offtopic discussion.

K.
 
C

Chad Perrin

Seriously though, compatibility layers *are* emulators, what they're not
is *full hardware* emulators. Unfortunately, when people think of
emulators, they think of the likes of Vice, DOSBox, Stella, MAME, &c. So
to avoid the misconception that they're full hardware emulators, projects
like Wine avoid the label. But in the strict sense, a compatibility layer
*is* an operating system emulator because they trick the software
running on top of them into thinking they exist in a different
environment than they really are: it emulates Windows, not the machine
running it.

Something like WINE is "an emulator" in the sense that you can open a
dictionary of the English language and find justification for using the
word "emulator" in that manner, but not in the sense that it fits into a
class of software technically known as "an emulator": it is
differentiated from a "true" emulator not only by lack of hardware
emulation, but also by virtue of the fact that it is not an emulation
environment. It's essentially just an API.
 
R

Ryan Davis

Ryan, googling for

"ruby inline" windows

gave me no usable hint among the first 50 results besides using
cygwin. Do you have a link to the reports you mention?

Maybe I should have written that giving that I'm using the One
Click Installer, don't have the Windows compiler toolchain, and am
not willing to use cygwin, I can't use Ruby Inline. Is this better?

It should work with the 1-click installer, but yeah... not without a
compiler. so there is no way to even expect it to work.
But, instead I might try to use Ruby Inline with MinGW, so thanks
for the question.

I've not used mingw, and have no idea if others have.
 
A

Austin Ziegler

So what is the source of the reluctance to use CygWin in the Ruby community?

It's crap and doesn't mesh well with Windows itself.

I have even recently (mostly) dumped it in favour of xming, because I
was *only* using cygwin for X services.

-austin
 
M

M. Edward (Ed) Borasky

Austin said:
It's crap and doesn't mesh well with Windows itself.

I have even recently (mostly) dumped it in favour of xming, because I
was *only* using cygwin for X services.

-austin
Ah ... I only use the client-side stuff, not the server "emulations". I
use the CygWin Perl extensively, plus the command line and the X server.
Once in a while, I need an open source piece of software that doesn't
have a native Windows build ... at that point my first attempt is to
compile and run it under CygWin. If that fails, I have a Gentoo Linux
VMware virtual machine I use.

I suppose I should try Xming ... as long as it has a usable command
line, I can get to ActiveState Perl.
 
M

MonkeeSage

Ok, I need to preface this by saying that I'm in no way either a C or
ruby guru, so I may have missed something here, but this is what I'm
seeing. The bottle-neck here is in the printing to screen.

I don't see how the OP got the code to run in 5 seconds while using any
stdout writing function (e.g., printf). The program should print like 4
megs of text to the screen (though I couldn't get the C that was posted
to compile--like I said, I'm no C superstar) -- there's no way that is
happening in 5 seconds.

Taking a very simple test case, which just prints a 10 byte char array
15000 times using puts:

--------

#include <stdio.h>
#define SIZE 15000
int main() {
char str[11] = "ABCDEFGHIJ";
int i;
for (i = 0; i < SIZE; ++i) {
puts(str);
}
printf("Printed %i bytes of data\n\0", SIZE*strlen(str));
return 0;
}

--------

Compiled with:

gcc -o test test.c

This yields:

time ./test

ABCDEFGHIJ
ABCDEFGHIJ
....
ABCDEFGHIJ
Printed 150000 bytes of data

real 0m25.621s
user 0m0.010s
sys 0m0.029s


Now, let's see how Ruby's stdout writing stacks up:

--------

#!/usr/bin/ruby -w
SIZE = 15000
str = "ABCDEFGHIJ"
1.upto(SIZE) {
STDOUT.syswrite("#{str}\n")
}
STDOUT.syswrite("Printed #{SIZE*str.length} bytes of data\n")

--------

This yields:

ABCDEFGHIJ
ABCDEFGHIJ
....
ABCDEFGHIJ
Printed 150000 bytes of data

real 0m26.796s
user 0m0.202s
sys 0m0.049s

Pretty comparable there.


Of course, the bottle-neck was *supposedly* the maths and array access
and such, which is where C would excel (I'm not denying that ruby is
sometimes pretty slow, or that C is *much* faster all around, just bare
with me here).


So with one ruby implementation of the program mentioned on here:

--------

#!/usr/bin/ruby -w

Wd = (ARGV.shift || 5).to_i
$board = []

# Generate all possible valid rows.
Rows = (0...Wd ** Wd)\
.map { |n| n.to_s(Wd)\
.rjust(Wd,'0') }\
.reject{ |s| s =~ /(.).*\1/ }\
.map { |s| s.split(//)\
.map { |n| n.to_i + 1 }
}

def check (ary, n)
ary[0, n + 1].transpose.all? { |x| x.size == x.uniq.size }
end

def add_a_row (row_num)
if (Wd == row_num)
STDOUT.syswrite($board.map { |row| row.join }.join(':'))
else
Rows.size.times { |i|
$board[row_num] = Rows
if (check($board, row_num))
add_a_row(row_num + 1)
end
}
end
end

add_a_row(0)

---------

This took like 48 minutes! Ouch! But if that syswrite (or puts in the
original version) is replaced with a file write:

--------

def add_a_row (row_num)
if Wd == row_num
$outfile << $board.map { |row| row.join }.join(':')
else
Rows.size.times { |i|
$board[row_num] = Rows
if (check($board, row_num))
add_a_row(row_num + 1)
end
}
end
end

$outfile = File.open('latins.dump', 'wb')
add_a_row(0)
$outfile.close

--------

Now we're down to 16 minutes. Much better! But still...


Ok, so what about the implementation using the permutation and set
classes?

--------

#!/usr/bin/ruby -w

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 { |p|
s = SortedSet.new
$perms.each_with_index { |o, i|
o.each_with_index { |v, j| s.add(i) if p[j] == v }
} && s.to_a
}

$latins = []
def search lines, possibs
return $latins << lines if lines.size == $size
possibs.each { |p|
search lines + [p], (possibs -
$filter[p]).subtract(lines.last.to_i..p)
}
end

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

$latins.each { |latin|
$perms.each { |perm|
perm.each { |p| STDOUT.syswrite($out[latin[p]] + "\n") }
STDOUT.syswrite("\n")
}
}

--------

26 minutes...that's still gonna leave a mark. But the file IO version
of the same program?

--------

outfile = File.open('latins.dump', 'wb')
$latins.each { |latin|
$perms.each { |perm|
perm.each { |p| outfile << $out[latin[p]] << "\n" }
outfile << "\n"
}
}
outfile.close

--------

time ruby test.rb

real 0m17.227s
user 0m13.969s
sys 0m1.399s

17 seconds! WOOHOO! Yes, indeedy. That's more like it. Try it if you
don't believe me.



So the moral of the story is twofold:

1.) Don't assume the bottle-neck is in the interpreter and just run off
and start writing everything in C or Java or simplified Klingon or
whatever. Testing and coverage and profiling is the key to discovering
the true cause of your woes. Here the bottle-neck was in the writing 4+
megs to stdout -- and going to C won't help for that, contra the claims
of the OP.

2.) Don't write a crapload of text to stdout. It won't be as fast as
you'd like it to be no matter what language you use.


========

NB: All testing was done on:

Linux 2.6.17-gentoo-r5 #2 PREEMPT Thu Aug 10 14:21:37 CDT 2006 i686 AMD
Athlon(tm) XP 1600+ AuthenticAMD GNU/Linux

gcc version 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.9)

GNU C Library development release version 2.4

ruby 1.8.5 (2006-08-18) [i686-linux]

========


Regards,
Jordan
 
M

Minkoo Seo

Well put. I totally agree with you.

I'd like to mention that you can use inline for this purpose.
Have a look at
http://on-ruby.blogspot.com/2006/07/rubyinline-making-making-things-faster.html

In the article, ruby and inlined c version of prime nubmer checking is
compared. As expected, inlined C runs very fast compared to ruby only
version.

I also have an experience of porting to C++. My application
which heavily relied on matrix and log functions took more than
2 days to finish. After I've ported it to C++, it took about 6hrs.
Yes, it was amazing performance boost.

Sincerely,
Minkoo Seo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top