Re: performance question
Olivier Scalbert wrote:
Hello,
I would like to show to somebody how different languages look like by
doing a very simple case.
I was very surprised by the poor performance of the java version !
Here are the programs in different languages:
in C:
#include <stdio.h>
int main()
{
int i;
for(i = 0; i < 1000000; i++)
{
printf("abcdefghijk %d\n", i);
}
return 0;
}
time ./test1 > out.txt
real 0m0.710s
user 0m0.576s
sys 0m0.124s
in java:
public class Test
{
public static void main(String[] args)
{
for (int i = 0; i < 1000000; i++)
{
System.out.println("abcdefghijk " + i);
}
}
}
time java Test > out.txt
real 0m12.364s
user 0m4.180s
sys 0m7.676s
time java -server Test > out.txt
real 0m10.537s
user 0m3.120s
sys 0m6.544s
That is not good at all !
ols@tatooine:~/projects/ruby$ java -version
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b05)
Java HotSpot(TM) Client VM (build 1.6.0_02-b05, mixed mode, sharing)
ols@tatooine:~/projects/ruby$ uname -a
Linux tatooine 2.6.22-14-generic #1 SMP Sun Oct 14 23:05:12 GMT 2007
i686 GNU/Linux
In python:
i=0
while i < 1000000:
print "abcdefghijk", i
i=i+1
time python test.py > out.txt
real 0m2.292s
user 0m2.064s
sys 0m0.112s
In perl:
for ($count = 0; $count < 1000000; $count++)
{
print "abcdefghijk $count\n";
}
time perl test.pl > out.txt
real 0m1.243s
user 0m1.060s
sys 0m0.160s
In ruby:
counter = 0
while counter < 1000000
puts("abcdefghijk #{counter}")
counter+=1
end
time ruby test.rb > out.txt
real 0m4.731s
user 0m4.452s
sys 0m0.100s
As you can see the java program performance is far from the other one. I
was very surprised! Before the tests, I was sure that the winner will be
C followed by java, but it is not the case ...
Of course, I can improve the performance of the java version, by using a
StringBuffer, and print this buffer when it is bigger than a given size,
but it is not fair !
If you have any ideas, there are welcomed !
Thanks,
Olivier
I did my own benchmarks using these files:
bench.c:
#include <stdio.h>
#include <time.h>
void bench() {
long foo = 0;
clock_t start = clock();
for (long i = 1; i < 5000; ++i) {
for (long j = 1; j < i; ++j) {
if ((i % j) == 0) {
foo ++;
}
}
}
clock_t end = clock();
printf("%d %dms\n", foo,
(int) ((end - start) * 1000 / CLOCKS_PER_SEC));
}
int main() {
for (long i = 1; i < 10; ++i) {
printf("%d: ", i);
bench();
}
}
Bench.java:
public class Bench {
static final long CLOCKS_PER_SEC = 1000;
static void bench() {
int foo = 0;
long start = System.currentTimeMillis();
for (int i = 1; i < 5000; ++i) {
for (int j = 1; j < i; ++j) {
if ((i % j) == 0) {
foo ++;
}
}
}
long end = System.currentTimeMillis();
System.out.printf("%d %dms\n", foo,
(int) ((end - start) * 1000 / CLOCKS_PER_SEC));
}
public static void main(String[] args) {
for (int i = 1; i < 10; ++i) {
System.out.printf("%d: ", i);
bench();
}
}
}
Then ran these:
-bash-3.00$ java -version
java version "1.5.0_09"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode, sharing)
-bash-3.00$ javac Bench.java
-bash-3.00$ g++ --version
g++ (GCC) 3.3.3 (NetBSD nb3 20040520)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
-bash-3.00$ java -server Bench
1: 38357 457ms
2: 38357 416ms
3: 38357 401ms
4: 38357 394ms
5: 38357 394ms
6: 38357 401ms
7: 38357 395ms
8: 38357 401ms
9: 38357 394ms
-bash-3.00$ java -client Bench
1: 38357 421ms
2: 38357 400ms
3: 38357 394ms
4: 38357 400ms
5: 38357 393ms
6: 38357 393ms
7: 38357 400ms
8: 38357 394ms
9: 38357 401ms
-bash-3.00$ ./bench
1: 38357 450ms
2: 38357 440ms
3: 38357 450ms
4: 38357 430ms
5: 38357 450ms
6: 38357 440ms
7: 38357 450ms
8: 38357 440ms
9: 38357 450ms
This looks to me like the c version is slower...
--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>