자바 vs C 성능비교

select99의 이미지
1244
points
7
points

자바가 C 와 성능차가 별로 안난다는 사람들혹은 글들을 종종 봅니다.

과연 그주장이 맞는지 직접 테스트해보았습니다.

일단 자바측에서 주장한 간단한 소스하나를 가져왔습니다.

==========================

public class Speed_K {
  static boolean c1 = true, c2=true;
  public static void main(String[] args) {
    long start = 0, end = 0, elapsed;
    try {Thread.sleep(5000L);} catch (InterruptedException e) {}



    for(int k=0; k<5; k++) {
      start = System.currentTimeMillis();
      if( end == 0 ) end = start;
      doo( (int)((end - start)/1000));
      end = System.currentTimeMillis();
      System.out.println("Elapsed time:"+((end-start)/1000.));
    }
  }

  static public int doo( int in ){
    int i,j;
    int count = 5;
    int n = 50000000;
    int sum =0;

n = n + in;
    for(i=0; i< count;i++) {
      for(j=0; j<n;j++){
        if ( c1 == true){
          if (c2 == true) { sum ++;}
          else { sum--; }
        }
      }
      c2 = ! c2;
    }
    return sum;
  }
}

========================================

#include <sys/time.h>
#include <stdio.h>
double elapse_tm( void );


int c1 = 1, c2=1;
int main( void )
{
int k;
    long start, end, elapsed;
    double dd;

    printf( "sizeof int=%d long=%d\n", sizeof(int), sizeof(long));
elapse_tm();
    for( k=0; k<5; k++)
    {
      doo( (int) dd );

      printf("Elapsed time:%f\n", (dd = elapse_tm()));
    }
}

int doo( int in )
{
    int i,j;
    int count = 5;
    int n = 50000000;
    int sum =0;

n = n + in;
    for(i=0; i< count;i++) {
      for(j=0; j<n;j++){
        if ( c1 == 1){
          if (c2 == 1) { sum ++;}
          else { sum--; }
        }
      }
      c2 = !c2;
    }
    return sum;
}

double elapse_tm( void )
{
        static struct timeval et = { 0, 0 };
        struct timeval st;

        st = et;
        gettimeofday( &et, NULL );

        if( st.tv_sec == 0 && st.tv_usec == 0 ) return 0;
        return et.tv_sec - st.tv_sec + ( et.tv_usec - st.tv_usec ) / 1000000.;
}

=====================================================
소스가 약간달라 비슷하게 개선되었습니다.
=====================================================

컴파일옵션 -O3

결과

[localhost test_src]$ java Speed_K
Elapsed time:1082
Elapsed time:1054
Elapsed time:1160
Elapsed time:1181
Elapsed time:1204
[localhost test_src]$ cc -O3 Speed_K.c
[localhost test_src]$ ./a.out
Elapsed time:0.249474
Elapsed time:0.250046
Elapsed time:0.249660
Elapsed time:0.249515
Elapsed time:0.250348

자바는 밀리세컨드 C는 초단위 따라서 자바는 1.1 초정도이고 C는 0.25 초 정도입니다.
제가해본바로는..무려 400%의 성능차가나는데..

더구나 동일코드상으로는 C가 최척화되어 결과가 0에 가까웠습니다.
그래서 보시다시피 최적화 되지못하게 불리한코드 dd변수를 추가하였는데도불구하고 훨씬빠르네요.

자바가 어떤옵션으로 더욱성능이 증가된다거나 하는것이 있으면 테스트후 결과좀 올려주세요..

---컴파일러.-------
[localhost test_src]$ java -version
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)

[localhost test_src]$ cc --version
cc (GCC) 4.1.1 20070105 (Asianux 3.0 4.1.1-52.2.1)
Copyright (C) 2006 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.

M.W.Park의 이미지
6923
points

단순히 눈으로

1
point

단순히 눈으로 봐도,
java 쪽의 결과는 좀 이상한데요?
혹시 sun의 jdk말고 다른거 쓰셨는지요?

제경우에는 거의 대부분의 성능 테스트에서 처음 한번은 매우 느리게 실행되고, 그다음부터는 빨라졌던거같은데요.

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

select99의 이미지
1244
points

sun 의 jdk 입니다..

1
point

sun 의 jdk 입니다..

purple의 이미지
1141
points

HotSpot 최적화 옵션을 주면 달라집니다.

2
points

최적화 옵션을 주면 달라집니다.

저의 경우는 (loop 를 5번이 아니라 15번 돌게 했습니다)

먼저 client vm 의 경우

purple@localhost:~/speed$ java Speed_K
Elapsed time:1409
Elapsed time:1360
Elapsed time:1348
Elapsed time:1381
Elapsed time:1346
Elapsed time:1393
Elapsed time:1348
Elapsed time:1377
Elapsed time:1349
Elapsed time:1378
Elapsed time:1358
Elapsed time:1446
Elapsed time:1459
Elapsed time:1376
Elapsed time:1362

server vm 인 경우

purple@localhost:~/speed$ java -server Speed_K
Elapsed time:1853
Elapsed time:1873
Elapsed time:42
Elapsed time:42
Elapsed time:43
Elapsed time:42
Elapsed time:42
Elapsed time:42
Elapsed time:41
Elapsed time:42
Elapsed time:42
Elapsed time:42
Elapsed time:41
Elapsed time:41
Elapsed time:42

가 나왔습니다.

JVM 은
purple@localhost:~/speed$ java -server -version
java version "1.6.0"
OpenJDK Runtime Environment (build 1.6.0-b09)
OpenJDK Server VM (build 1.6.0-b09, mixed mode)

입니다.

select99의 이미지
1244
points

저와 환경이

2
points

저와 환경이 다른면이 있겠습니다만..
제가돌려보니..
test_src]$ java -server Speed_K
Elapsed time:1075
Elapsed time:1066
Elapsed time:492
Elapsed time:492
Elapsed time:516

두번은 같고 세번은 반정도 줄었습니다..
그래도 2배정도의 성능차는 나네요

또한 자바또한 최적화룰이 적용된거같은데..

select99의 이미지
1244
points

C 도 -O3 옵션으로

2
points

C 도 -O3 옵션으로 컴파일실행한 결과좀 올려주실수 있으신지...

winner의 이미지
4336
points

최적화 option을 다양화시켜서 측정할 필요가 있을 것 같은데요.

2
points

예전의 제 경험상 -O3가 -O2보다 항상 느렸었습니다.
지금은 또 많이 상황이 변했을테지만요.

Program의 특성에 따라서 -O1이 -O2보다 빠른 경우도 있다고 들었습니다. (Visual C++의 경우)
Code size를 위주로한 최적화가 cache 적중률을 높이기 때문이라죠.

제 생각에 공신력 있는 test들은 역시 앞서 소개되었던 site들이 아닐까 싶네요.
지금 이 논의는 상당히 지엽적인 수준을 이야기하고 있을지 모르겠습니다.
올리신 code에 대해서 집중해서 논의를 하고 싶은 것이라면 의미가 있겠습니다만...

select99의 이미지
1244
points

딱히 정한다기보다

1
point

딱히 정한다기보다 어느정도 빠른방법으로 옵션을 선택해야겠죠...

site에 소개된 내용을 무조건믿을수는 없다는것입니다.
더구나 그site 들은 자바site 니까요..

지엽적일수 있습니다. 하지만 그건 java site 에서 제시한겁니다.
그만큼 java 가 유리한 특수한경우를 테스트해보는겁니다.

purple의 이미지
1141
points

C의 경우입니다.

1
point

C의 경우입니다.

purple@localhost:~/speed$ gcc -O3 speed_k.c
purple@localhost:~/speed$ ./a.out
Elapsed time:0.342452
Elapsed time:0.319901
Elapsed time:0.329845
Elapsed time:0.344676
Elapsed time:0.330628
Elapsed time:0.330346
Elapsed time:0.330183
Elapsed time:0.333312
Elapsed time:0.329467
Elapsed time:0.329447
Elapsed time:0.331011
Elapsed time:0.329315
Elapsed time:0.330824
Elapsed time:0.332722
Elapsed time:0.330069

purple@localhost:~/speed$ gcc --version
gcc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7)
Copyright (C) 2007 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.

ditto의 이미지
5500
points

(썩은 떡밥?)

2
points

http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=gcc&la...

gcc 옵션은 -O3 -fomit-frame-pointer -march=pentium4라고 합니다.

select99의 이미지
1244
points

썩은떡밥? 옵션이

2
points

썩은떡밥?

옵션이 정확히 어떻게 작동하는지까지야 알수 없지만
전 AMD 인데도 성능차이 많이 나거든요...

shame2의 이미지
1324
points

-march=athlon64

2
points

-march=athlon64

ditto의 이미지
5500
points

제가 썩은

2
points

제가 썩은 떡밥이라고 한 이유는 이미 이런 주제가 많이 올라왔기 때문이죠. 어떤 식으로든 결론은 생산성이 중요한 경우에는 자바를, 성능이 정말 크리티컬한 경우는 C/C++를 써라, 어떤 경우에는 자바가 더 빠를 수도 있다...로 나는 것 같습니다.
그리고 이런 벤치마크는 환경이나 수행하는 작업에 따라 엄청난 차이가 날 때도 있으니까 별 의미 없다는 겁니다.
혹시 장장 7페이지에 달하는 토론을 다시 하고 싶으신건가요? http://kldp.org/node/73324

눈아파 죽겠네요.

1
point

눈아파 죽겠네요. 괜히 클릭하는 바람에 저거 7페이지 다 읽었습니다. -_-a
두페이지째 부터는 안볼라 그랬는데, 보던게 아까워서 조금만 더 하다가...

며칠전에 누군가가 국내 모 항공사에서는 90년대 초반까지 어셈블리로 어플리케이션을 개발했다고 하는 이야기를 듣고,
말도 안되는 소리라고 하고 넘어간적이 있는데... 저거 읽다 보니 그럴 수도 있을 수 있겠다는 생각이 드네요. ㅋㅋ

--
Jeong
http://www.pdfpro.co.kr/blog/jeong

Re:

1
point

제가 듣기로는 British Airway도 90년대 중후반까지는 어셈블리어를 사용했다고 하더군요.

select99의 이미지
1244
points

저글에도 있듯이..

2
points

저글에도 있듯이.. 자바가 생산성이 좋다는 근거는 없다고 봅니다.

수행하는작업에따라 자바가 빠른경우도 있을것같지만 그걸 C로 했으면 더빠르게 될것이라는거죠..

100번을 다시토론한다고 나쁜가요? 길고짧음은 가려봄직하고 서로가 다르게 알고 있다면 정답도 있을겁니다.

그걸 알아가는게 나쁜가요.. 전 근거없이 이건이러니 이유는따지지말고 그런줄알고 더이상 말하지말라 라고하는게 더이상하다고 보는데요..

Re:

2
points

1 일반적으로 C로 만든 어플리케이션의 실행 속도가 자바로 만든 어플리케이션의 그것보다 빠르다고 평가받고 저도 그것에 동의합니다.

2 그러나 프로그래머의 생산성과 프로그램의 실행 속도는 서로 다른 개념입니다. 생산성의 정의와 그것을 측정하는 방법에 관해서 SE 책을 한 번 참고하시기 바랍니다.

3 자바는 메모리 관리나 포인터를 없앰으로 해서 C보다 생산성이 좋다는 것이 일반적인 평가이고 저도 그것에 동의합니다.

select99의 이미지
1244
points

:"자바는 메모리

1
point

자바는 메모리 관리나 포인터가 없어 기호화되고 더함축적이지 못하며 필요한경우 메모리를직접컨트롤할수없어 생산성이 떨어진다고 봅니다.

최소한 C는 자바처럼 구현할수도 있으니 자바보다 못할이유는 없다고 봅니다.

다른 분들이 말씀하시는 '생산성' 과는 의미가 달라보입니다.

1
point

같은 단어로 다른 의미를 두고 토론을 하면 더 이상 토론이 진행되지 않습니다.

select99의 이미지
1244
points

어떤의미로

1
point

어떤의미로 말씀하신건가요..

kwon37xi의 이미지
3140
points

select99님의 생산성은

1
point

select99님의 생산성은 "프로그램 수행 속도"를 의미하고,
다른 분들의 생산성은 "어떤 일을 하는 코드를 얼마나 더 빨리 짤 수 있는가"입니다.

Java로 할 수 있는 일을 C/C++로 못한다거나 혹은 더 빨리 "작동"하게 만들 수 있다는 의미가 아닙니다.
Java로 짜면 C/C++보다 같은 일을 하는 프로그램을 "더 일찍" 작성할 수 있다는 겁니다.
그럴 수 있는 이유중에 하나는, Java로 작성할 때는 C에서 처럼 메모리 릭을 방지하는 코드를 작성하지 않아도 되기 때문에, 신경쓸게 줄어들거든요.

JVM은 작동중에 스스로 최적화를 합니다.

일반적으로 Java에서 웹 애플리케이션을 작성할 때, 정적인 파일(이미지, *.js, *.css)등은 C로 짠 아파치가 처리하게 하고, JSP/Servlet 처리는 Java WAS(Tomcat)가 처리하도록 설정을 하는데요, 왜냐면 정적 파일 서빙은 C로 짠 아파치가 훨씬 빠르거라고 생각하기 때문이지요.

그러나 O'Reilly에서 나온 Tomcat Definitive Guide 2nd Edition ( http://oreilly.com/catalog/9780596101060/index.html )에 따르면 그게 낭설이라고 합니다.

Tomcat(Java로 만들어진 웹 서버/JSP/Servlet 처리기)과 Apache 2로 정적 파일 전송 테스트 결과 장시간 테스트를 반복하면 Apache 2 보다 Tomcat 6의 정적 파일 서빙 속도가 더 빠르다는 결과가 나옵니다. 정확한 원인은 모르지만, 저자의 의견에 따르면 JVM의 수행시 최적화 때문에 이런 현상이 나오는게 아닌가 하는 의견이 있습니다.

어쨌든 저도, 수행 속도 관련 논쟁은 더 이상 별 의미는 없는 것 같은데요..

http://kwon37xi.egloos.com

select99의 이미지
1244
points

님이

1
point

님이 오해하셨군요..
저또한 생산성을 님과 같은의미로 말한겁니다.
수행속도는 속도구요 생산성이란 얼마나 더빨리짤수 있는가를 두고 말한것입니다.

기호화되지 못했기에 코드작성이 느리다는것이구요.
메모리를 직접컨트롤할수없기때문에.. 동일한 성능의 프로그램을 작성하기위해 매우 난해하게 풀어가야한다는것이 결국 생산성(프로그래밍 자체가) 느리다는것 입니다.

자바로짜면 c/c++ 보다 같은일을 하는프로그램을 더일찍 작성할수 있다고 하셨는데.
자바로짠것은 c/c++로도 그대로 거의 흡사하게 짜진다는겁니다. 그런데 왜 자바가 더빨리짜지냐는거죠..

보통 웹에서 java로 동적페이지를 서비스한다는데.. c로 안하는이유는 java 가 그쪽에 이미 많이 진출했기때문에 lib 등이 풍부하다고 봅니다...

그러나 c가 웹lib 가 없는것도 아니며 속도가 떨어지지도 않습니다. fastcgi 라는것도 있구요..
c 가 웹쪽진출이 잘안됬던것은 c가 다른많은 분야가 있는데반해 웹쪽이 좀 노가다(?)성이 있어 개발자들이 비선호했었던 이유도 있을겁니다.

질문

2
points

인용:
기호화되지 못했기에 코드작성이 느리다는것이구요.

어떤 뜻인지 해석이 잘 안되어서요. 혹시 언어차원에서의 syntax 지원하는 것이 적다는 것을 의미하시는건지요?

인용:
메모리를 직접컨트롤할수없기때문에.. 동일한 성능의 프로그램을 작성하기위해 매우 난해하게 풀어가야한다는것이 결국 생산성(프로그래밍 자체가) 느리다는것 입니다.

잘못 오해하면 '스크립트 언어가 C/C++ 보다 생산성이 느리다' 도 해석가능할 수 있을 듯 합니다만. 그리고 자바의 생산성은 자바 언어 자체보다 자바 + 개발환경을 같이 보셔야 할 것 같습니다. smalltalk 가 smalltalk 언어 신텍스만이 아닌 smalltalk 언어 환경을 같이 봐야 하듯이요. 실전에서 '동일 환경을 위해 VIM + Console 상태로만 비교하자' 하진 않을테고요.

인용:
자바로짜면 c/c++ 보다 같은일을 하는프로그램을 더일찍 작성할수 있다고 하셨는데.
자바로짠것은 c/c++로도 그대로 거의 흡사하게 짜진다는겁니다. 그런데 왜 자바가 더빨리짜지냐는거죠..

자바도 그리 성에 차진 않지만, C++ 에서 Reflection/Introspection 을 이용한 Framework 가 있는지요? 저는 언어차원에서 이것이 지원되는 순간 프레임워크에서 다룰 수 있는 추상 정도가 다르다고 생각합니다. 혹은 AOP 같은 Meta-Programming 이라던지요.

dormael의 이미지
3542
points

덥썩

1
point

이 테스트에서는 아직 두 런타임의 기본(원시) 데이터 타입에 대한 정의가 확실하지 않기 때문에 정확한 테스트라고 볼 수 없습니다.

파닥파닥

select99의 이미지
1244
points

물론C int

2
points

물론C int 32비트입니다. long 으로 해도 동일한속도가 나오죠.

dormael의 이미지
3542
points

자바의 경우 long은

2
points

자바의 경우 long은 signed 64bit, int는 signed 32bit 입니다만.

연산자나 원시 타입의 재정의가 불가능하다는 약점이 있습니다.

최적화를 모두 빼고 비교 한다고 해도 이런 퍼포먼스 비교에서 자바가 C보다 빠르거나 비슷한 속도를 내는건 불가능한 일입니다.

그렇다고 C코드를 자바와 같은 원시 타입을 쓰고 테스트 해야 한다고 하면 억지 부린다고 하시겠죠?

즉, 이런 퍼포먼스 테스트를 정말 할 필요가 있을까 생각이 듭니다.

ㅋㅋ

select99의 이미지
1244
points

동일하게 32비트로

1
point

동일하게 32비트로 테스트해야 맞다고 봅니다.
한쪽은 32인데 한쪽은 64라면 불공평한거죠..

맛있는 떡밥이군요 :)

1
point

코드를 몇 줄 수정해봤습니다.
수정한 부분은 indentation을 달리했습니다.

swhan@swhan:tmp $ cat Speed_K.java 
public class Speed_K {
  static boolean c1 = true, c2=true;
  public static void main(String[] args) {
    long start, end, elapsed;
    try {Thread.sleep(5000L);} catch (InterruptedException e) {}

    for(int k=0; k<5; k++) {
      start = System.currentTimeMillis();
long ret = doo();
      end = System.currentTimeMillis();
System.out.println("Elapsed time:"+(end-start) + " ret=" + ret);
    }
  }

  static public long doo(){
int sumcount = 0;
    int i,j;
    long count = 5;
    int n = 50000000;
    long sum =0;

    for(i=0; i< count;i++) {
      for(j=0; j< n;j++){
        if ( c1 == true){
          if (c2 == true) { sum ++;}
          else { sum--; }
++sumcount;
        }
      }
      c2 = ! c2;
    }
//return sum;
return sumcount;
  }
}

---

swhan@swhan:tmp $ cat x.c
#include 
#include 
double elapse_tm( void );


int c1 = 1, c2=1;
int main( void )
{
    int k;
    long start, end, elapsed;
    double dd;

    elapse_tm();
    for( k=0; k<5; k++)
    {
int l_ret = doo( (int) dd );

printf("Elapsed time:%f - ret=%d\n", (dd = elapse_tm()), l_ret);
    }
}

int doo( int in )
{
int sumcount=0;
    int i,j;
    int count = 5;
    int n = 50000000;
    long sum =0;

n = n+ in;
    for(i=0; i< count;i++) {
      for(j=0; j< n;j++){
        if ( c1 == 1){
          if (c2 == 1) { sum ++;}
          else { sum--; }
++sumcount;
        }
      }
      c2 = ! c2;
    }
//return sum;
return sumcount;
}

double elapse_tm( void )
{
        static struct timeval et = { 0, 0 };
        struct timeval st;

        st = et;
        gettimeofday( &et, NULL );

        if( st.tv_sec == 0 && st.tv_usec == 0 ) return 0;
        return et.tv_sec - st.tv_sec + ( et.tv_usec - st.tv_usec ) / 1000000.;
}

다음은 실행 결과입니다.

swhan@swhan:tmp $ javac Speed_K.java 
swhan@swhan:tmp $ java -server Speed_K ;java  Speed_K
Elapsed time:865 ret=250000000
Elapsed time:907 ret=250000000
Elapsed time:410 ret=250000000
Elapsed time:412 ret=250000000
Elapsed time:412 ret=250000000
Elapsed time:1065 ret=250000000
Elapsed time:1193 ret=250000000
Elapsed time:1210 ret=250000000
Elapsed time:1186 ret=250000000
Elapsed time:1214 ret=250000000
swhan@swhan:tmp $ gcc -O3 x.c -o x3; gcc x.c -o x0
swhan@swhan:tmp $ ./x3;./x0
Elapsed time:0.766235 - ret=250000000
Elapsed time:0.761897 - ret=250000000
Elapsed time:0.760770 - ret=250000000
Elapsed time:0.761476 - ret=250000000
Elapsed time:0.764290 - ret=250000000
Elapsed time:1.011169 - ret=250000000
Elapsed time:1.012441 - ret=250000005
Elapsed time:1.016509 - ret=250000005
Elapsed time:1.015752 - ret=250000005
Elapsed time:1.015788 - ret=250000005

환경입니다.

swhan@swhan:tmp $ uname -a
Darwin swhan.lan 9.4.0 Darwin Kernel Version 9.4.0: Mon Jun  9 19:30:53 PDT 2008; root:xnu-1228.5.20~1/RELEASE_I386 i386 i386
swhan@swhan:tmp $ gcc -v
Using built-in specs.
Target: i686-apple-darwin9
Configured with: /var/tmp/gcc/gcc-5484~1/src/configure --disable-checking -enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib --build=i686-apple-darwin9 --with-arch=apple --with-tune=generic --host=i686-apple-darwin9 --target=i686-apple-darwin9
Thread model: posix
gcc version 4.0.1 (Apple Inc. build 5484)
swhan@swhan:tmp $ java -version
java version "1.5.0_13"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-b05-237)
Java HotSpot(TM) Client VM (build 1.5.0_13-119, mixed mode, sharing)
swhan@swhan:tmp $ javac -version
javac 1.5.0_13
---이하생략---

shame2의 이미지
1324
points

모드빈 커널인가여

1
point

모드빈 커널인가여 ㅋㅋㅋ
저도 바닐라 못쓴다는 ㅠ

hayarobi의 이미지
4121
points

XCODE 3.1이 나왔나요?

1
point

제 gcc는 5465빌드군요.

---------- 시그 *****
저도 세벌식을 씁니다.
M$윈도우즈, 리눅스, 맥 오에스 텐, 맥 오에스 클래식을 모두 엔드유저 수준으로 쓴답니다.
http://psg9.egloos.com

select99의 이미지
1244
points

코드가 좀달라 거의

1
point

코드가 좀달라 거의 비슷하게 맞추고
데이터 size도 넣어봤습니다.
-------------------------------------------------------------
혹시 시간되시면 결과를좀..

public class Speed_K {
  static boolean c1 = true, c2=true;
  public static void main(String[] args) {
    long start = 0, end = 0, elapsed;
    try {Thread.sleep(5000L);} catch (InterruptedException e) {}



    for(int k=0; k<5; k++) {
      start = System.currentTimeMillis();
      if( end == 0 ) end = start;
      doo( (int)((end - start)/1000));
      end = System.currentTimeMillis();
      System.out.println("Elapsed time:"+((end-start)/1000.));
    }
  }

  static public int doo( int in ){
    int i,j;
    int count = 5;
    int n = 50000000;
    int sum =0;

n = n + in;
    for(i=0; i< count;i++) {
      for(j=0; j<n;j++){
        if ( c1 == true){
          if (c2 == true) { sum ++;}
          else { sum--; }
        }
      }
      c2 = ! c2;
    }
    return sum;
  }
}

#include <sys/time.h>
#include <stdio.h>
double elapse_tm( void );


int c1 = 1, c2=1;
int main( void )
{
int k;
    long start, end, elapsed;
    double dd;

    printf( "sizeof int=%d long=%d\n", sizeof(int), sizeof(long));
elapse_tm();
    for( k=0; k<5; k++)
    {
      doo( (int) dd );

      printf("Elapsed time:%f\n", (dd = elapse_tm()));
    }
}

int doo( int in )
{
    int i,j;
    int count = 5;
    int n = 50000000;
    int sum =0;

n = n + in;
    for(i=0; i< count;i++) {
      for(j=0; j<n;j++){
        if ( c1 == 1){
          if (c2 == 1) { sum ++;}
          else { sum--; }
        }
      }
      c2 = !c2;
    }
    return sum;
}

double elapse_tm( void )
{
        static struct timeval et = { 0, 0 };
        struct timeval st;

        st = et;
        gettimeofday( &et, NULL );

        if( st.tv_sec == 0 && st.tv_usec == 0 ) return 0;
        return et.tv_sec - st.tv_sec + ( et.tv_usec - st.tv_usec ) / 1000000.;
}

다즐링의 이미지
5984
points

흠..

1
point

저랑 내기할까요?

심지어 자바보다 느린 파이썬으로 저는 코딩을 할테니 다음과 같은 조건을 가진 프로그램을 짜주세요.
"랜덤으로 만들어진 문자열에서 1글자를 찾는데 걸리는 시간, 단문자열은 ascii 에 한한다."
"랜덤으로 문자 만드는 시간은 제외"

------------------------------------------------------------------------------------------------
Life is in 다즐링

select99의 이미지
1244
points

네. 일단

1
point

네. 일단 시간되는데로 해보죠..

랜덤으로만들어진 문자열에서 랜덤시간제외라고 했기때문에 그냥 디파인하겠습니다.
차후 다른요구사항이 있으리라보고 일단 이렇게만올립니다.

#include <stdio.h>
#include <string.h>

int main( void )
{
char *str = "abcdefghijklmnopqrstuvwxyz";
printf( "%c \n", *strchr( str, 't' ));
return 0;
}

atie의 이미지
17994
points

count = 15로만

2
points

[EDIT - error on prev. post]

changed count = 15

$ cc -o sk sk.c
$ time ./sk
Elapsed time:2.487384
Elapsed time:2.399620
Elapsed time:2.441580
Elapsed time:2.403700
Elapsed time:2.446976

real	0m12.181s
user	0m12.166s
sys	0m0.007s

$ cc -march=core2 -O2 -pipe -o sk sk.c
$  time ./sk
Elapsed time:1.584491
Elapsed time:1.550165
Elapsed time:1.548172
Elapsed time:1.547281
Elapsed time:1.544337

real	0m7.776s
user	0m7.769s
sys	0m0.003s


$ cc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --prefix=/usr --enable-shared --enable-languages=c,c++,fortran,objc,obj-c++,treelang --enable-threads=posix --mandir=/usr/share/man --enable-__cxa_atexit --disable-multilib --libdir=/usr/lib --libexecdir=/usr/lib --enable-clocale=gnu --disable-libstdcxx-pch --with-tune=generic
Thread model: posix
gcc version 4.3.1 20080724 (prerelease) (GCC) 

$ time java Speed_K
Elapsed time:1919
Elapsed time:1927
Elapsed time:54
Elapsed time:55
Elapsed time:54

real	0m9.139s
user	0m4.106s
sys	0m0.030s

$ java -version
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b32)
Java HotSpot(TM) Server VM (build 14.0-b01, mixed mode)

예를 들어 gcc에 core2 arch를 줄 수 있는 것도 최근 버전에서고, Java 1.6도 빌드 버전에 따라 HotSpot의 성능이 다르니 각각의 버전을 올려서 몇 번 더 테스트 해 보세요. 그리고 참고로...
http://weblogs.java.net/blog/kohsuke/archive/2008/03/deep_dive_into.html
http://blogs.sun.com/jag/entry/hotspot_performance
----
I paint objects as I think them, not as I see them.
atie's minipage

select99의 이미지
1244
points

옵션을 -O3 이상으로

1
point

옵션을 -O3 이상으로 줘보실래요..
-O2 이하는 성능이 제대로 안나오는듯합니다.

atie의 이미지
17994
points

저는 -O3로 제가 쓰는

3
points

저는 -O3로 제가 쓰는 패키지를 컴파일하지 않습니다. java 1.6 (어느 버전? or 1.7?) 이상에서는 HotSpot이 자동 적용이 되고, gcc의 -march=core2 -O2 옵션이면 제 기계에서는 안정적이고 그래도 최적화를 한다고 한 셈인데... 자바나 gcc 둘 다 최신 버전에 (둘다 거의 디폴트라 할 수 있는) 적당한 최적화가 적용된 비교라 제게는 위의 제 비교가 공평한 듯 합니다.

저는 dong1036님이 쓴 것처럼 왜 비교하는가 하는 쪽입니다. 위의 코드에 단순히 모든 sum 값을 줄별로 찍는 기능을 넣는다고 한다면 자바는 c에 비해 10배 이상은 족히 느립니다. 그런데, GUI 프로그램이라면 루프를 얼마나 빨리 돌고 printf를 얼마나 빨리 찍는지는 아시다시피 문제거리도 아니고요.

다만 제가 답글을 올리고 링크를 걸었던 이유는, 자바 1.6.0_01-b06 한 버전으로 비교해서 4배의 성능차가 있다고 이야기하는 것은 성급하니 버전을 올려서 몇 번 더 다른 테스트를 해 보라고 권했던 겁니다. (아마 그래서 글을 올린 것이라 짐작하고요.)
----
I paint objects as I think them, not as I see them.
atie's minipage

select99의 이미지
1244
points

"sum 값을 줄별로 찍는

1
point

"sum 값을 줄별로 찍는 기능을 넣는다고 한다면 자바는 c에 비해 10배 이상은 족히 느립니다"

위코드는 그나마 자바site 에서 "자바는 느리지 않다" 라는 코드중의 임의로 선택한것입니다.

저도 왜 저런코드로 작성해는지는 모르겠습니다만.. 자바에서 빠르게 동작하는 특수한?코드라고하더군요..

그래서 얼마나빠른지 정말빠른지 직접해보고 싶었습니다. 과연 느리지 않는지..
직접해보니.. 거기서주장한 것과 다르게 매우느리게 나오더군요..
물론 몇군데서 해봤습니다. 모두 비슷한결과였죠..
그래서 자바site 에서 자바가 느리지 않다고 주장하는건 잘못된것이 아닌가라고 생각되어진다는겁니다.

더구나 저런특수한것에서도 차이가나는데.. 일반적이면 얼마나 차이가 더크겠냐는거죠..

atie의 이미지
17994
points

제가 쓴 글의 부분을

2
points

제가 쓴 글의 부분을 인용하여 글을 전개한 것이 제게는 "이 분은 선입견을 갖고 있거나 의도적이구나"하게끔 느끼게 합니다.

제 테스트의 해석은,
c에서 -O2 최적화를 한다고 해도 예시된 코드의 수행은 3번째 루프 이후로는 자바가 30배쯤 빠르다.
입니다.

select99님의 결과가 그렇게 나오지 않는 것은,
사용한 자바 버전의 문제 또는 테스트 기계(AMD)의 CPU에 HotSpot의 최적화가 덜 된 탓이
이유입니다.

몇 군데 다른 테스트를 한 것도 올려봐 주세요. 비슷한 결과이면 적어도 제가 비교한 버전의 수행 결과를 AMD 기계에서 테스트 한 것을 올려봐 주시고요.

ps. 루프를 사용하는 것은 프로그램의 일반적인 경우입니다. 그게 특수한 코드이면, 그 루프 안에서 건 당 printf로 sum 값을 찍는 경우는 더 특수한 케이스가 됩니다.

----
I paint objects as I think them, not as I see them.
atie's minipage

김일영의 이미지
7361
points

최적화 옵션 잘 모릅니다만...

0
points

제가 O2, O3 뭐가 뭔지 잘 모르는 사람이긴 합니다만
Java를 HotSpot으로 돌리는 경우와 비교를 하려면
C 역시 Profile 기반의 최적화는 해야 격이 맞다고 생각됩니다.

gcc의 option에 따른 결과

0
points

gcc 컴파일 옵션 변경에 따른 결과값입니다.
소스는 원문 소스에서 변경한 것 없고
시스템은 Core2 Duo 6300에 Fedora Core 6입니다.
jdk나 gcc 버전은 아래 결과에 포함되어 있습니다.
제대로 컴파일 옵션을 주고 나면 속도가 비교가 안되네요.

=================================================

jhpark@crouter:~/a 176$java -version
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)
jhpark@crouter:~/a 31$java -server Speed_K
Elapsed time:0.997
Elapsed time:1.021
Elapsed time:0.387
Elapsed time:0.369
Elapsed time:0.387
jhpark@crouter:~/a 32$java -client Speed_K
Elapsed time:0.808
Elapsed time:0.807
Elapsed time:0.806
Elapsed time:0.807
Elapsed time:0.806
jhpark@crouter:~/a 178$gcc --version
gcc (GCC) 4.1.2 20070626 (Red Hat 4.1.2-13)
Copyright (C) 2006 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.

jhpark@crouter:~/a 33$gcc -O2 Speed_K.c -o a
jhpark@crouter:~/a 34$./a
sizeof int=4 long=4
Elapsed time:1.451029
Elapsed time:1.370664
Elapsed time:1.453891
Elapsed time:1.370636
Elapsed time:1.451029
jhpark@crouter:~/a 35$gcc -O3 Speed_K.c -o a
jhpark@crouter:~/a 36$./a
sizeof int=4 long=4
Elapsed time:0.134384
Elapsed time:0.134390
Elapsed time:0.134395
Elapsed time:0.134375
Elapsed time:0.134376
jhpark@crouter:~/a 37$gcc -fprofile-generate -O3 Speed_K.c -o a
jhpark@crouter:~/a 38$./a
sizeof int=4 long=4
Elapsed time:0.976994
Elapsed time:0.976884
Elapsed time:0.976423
Elapsed time:0.976341
Elapsed time:0.976097
jhpark@crouter:~/a 39$gcc -fprofile-use -O3 Speed_K.c -o a
jhpark@crouter:~/a 40$./a
sizeof int=4 long=4
Elapsed time:0.000002
Elapsed time:0.000052
Elapsed time:0.000014
Elapsed time:0.000025
Elapsed time:0.000010

굳이 비교 안해도..

2
points

자바쪽에서 제일 느린 것은 IO쪽인데..

어차피 프로그래밍을 하면.. IO는 거의다 사용하지요.. ㅡ,.ㅡ ㅋ

아무리 NIO가 나왔다 쳐도.. C보다는 현격히 느린편이지요..

다른건 성능차이가 별로 없어도.. 이건 확연하게.. 성능차이가 있는데..

뭐 그렇다고요 ㅋㅋ

-O2, -O3 최적화 많이 쓰나요?

1
point

쓰고 싶어도 컴파일러마다 동작이 다르거나, inlining 을 잘못 처리하거나,

function call stack 이 제대로 안나오거나 해서요 (함수 호출에 대하여 call 대신

jmp 나 아에 inlining 해버리는지라..)

인용:
저글에도 있듯이.. 자바가 생산성이 좋다는 근거는 없다고 봅니다.

수행하는작업에따라 자바가 빠른경우도 있을것같지만 그걸 C로 했으면 더빠르게 될것이라는거죠..

GC 가 기본 지원 되는 언어와 안되는 언어, Reflection & Retrospection 이 지원 될 때와 지원되지 않을 때 디자인될 수 있는 Framework 의 추상도 수준의 차이, Eclipse + Java 와 Eclipse + CDT 조합의 구현현황을 생각하면 (KScope 도 왠만한 자바 IDE 의 'Find Usage' 혹은 'Find Reference' 기능의 정확도에 비해 떨어집니다.) '자바가 생산성이 좋다는 근거는 없다' 는 말이 제겐 도무지 와닿지 않네요.

lifthrasiir의 이미지
7083
points

call stack이 제대로 안

2
points

call stack이 제대로 안 나오는 거야 디버깅할 때 문제가 되는 거니까 디버깅할 때만 끄면 되고, inlining이 잘못 처리된다는 건 무슨 의미입니까? 적어도 제가 아는 한 인라인화 때문에 프로그램의 의미가 바뀌는 일은 없습니다. (심지어 항상 인라인화가 되는 함수라도 포인터를 취할 경우 그 코드는 남습니다.) 혹시 어셈블리와 섞어 쓰시는 걸 말씀하시는 걸지도 모르겠군요.

Re:

1
point

저는 gcc 컴파일러에서 -O3 옵션을 사용하면 모든 함수를 인라인 함수로 취급하고 그리고 지나친 최적화로 인해 프로그램 기능의 왜곡의 가능성이 있다고 들었습니다. 제가 들은 것이 맞습니까?

lifthrasiir의 이미지
7083
points

-finline-functions 옵션이

2
points

-finline-functions 옵션이 켜지는 걸 말씀하신다면 아닙니다. 이 옵션이 켜지면 gcc는 작은 함수에 대해서 인라인화를 할지 하지 않을지 경험적인 방법으로 결정합니다.

그나저나 -O3을 켰다가 정말로 뒤통수를 맞은 적이 한 번 있긴 한데, 이 때는 프로그램에 버그가 있던 것이 나타나지 않았다가 최적화를 하고서야 나타난 것으로 나중에 확인되었습니다. (처음 봤을 때는 최적화가 프로그램 깨먹나 했죠.) 다른 경우는 아직 본 적이 없네요. 아, 컴파일러 버그는 자주 봅니다. C++ 템플릿으로 별 짓을 다 해서요 -_-;

call stack

1
point

call stack 이 제대로 안나오는 것이 꼭 '디버깅 때' 만 문제가 되질 않습니다. 유지보수를 위해 프로그램이 외부로 배포 된 뒤 문제가 발생했을 경우 call stack 이나 function pointer list 를 로그로 남깁니다. (윈도우즈의 경우 mini dump 나 Bug Trap 등을 이용하죠. http://www.codeproject.com/KB/applications/BugTrap.aspx) 모든 프로그램이란 한번에 완벽할 수 없기 때문입니다. 그래서 종종 프로그램의 초기 버전에서는 release 컴파일을 하더라도 전역 최적화 옵션을 끄거나 디버깅 정보를 남기기도 하죠. (보안 문제가 걸리는데, 이건 다른 논의로 해두죠)

그런데 최적화 옵션(O2,O3) 가 활성화 될 경우 앞에서 말씀드린대로 inlining 되면서 일부 call trace 남은 것들이 합쳐져버립니다. 안정화된 프로그램이면 몰라도 초기 버전의 경우 배포 뒤 유지보수 때 어려움이 있습니다.

그리고 컴파일러의 공격적인 최적화나 혹은 컴파일러의 버그로 inlining 이 잘못되는 경우가 종종 있습니다. 컴파일러도 결국 '프로그램' 이다 보니, 버전 별 혹은 플랫폼에 따라 어느정도 버그들은 있습니다. 개발하는 쪽이 최대한 안죽고 잘 버텨야 하는 서버 프로그램인지라 문제가 되었었고, 결론은 '컴파일 옵션보다는 아키텍쳐나 최적화된 알고리즘으로 해결하자' 가 였습니다.

lifthrasiir의 이미지
7083
points

디버깅 정보를

1
point

디버깅 정보를 남기기 위함이라면 뭐 이해는 하겠습니다만, gcc를 쓰신다면 아마 -fno-inline-functions 옵션으로 인라인화를 피해 갈 수 있지 않나 싶습니다. 빠른 컴파일을 위해 -O2를 쓸 수도 있는 것이니까 선택의 문제겠네요.

컴파일러에서 최적화를 하다가 뻗는 문제는 -- 위에서 말했지만 실제 프로그램의 버그 때문에 그런 거 말고 -- 아직 겪은 적은 없습니다. 컴파일러 버그는 오히려 언어의 obscure한 부분(C++ 템플릿 약간 복잡하게 썼다고 터지더군요. 그 이후로 boost만 씁니다.)을 건들 때 더 많이 나타나는 것 같습니다. C/C++ 공부가 아직 부족한 걸지도 모르겠습니다 ;)

winner의 이미지
4336
points

Comeau사 꺼 사셔야 할 듯... ^_^

1
point

아, 그러면 다른 사람들과 작업하기 곤란한가? -_-.

lifthrasiir의 이미지
7083
points

언어 자체의 구현이

1
point

언어 자체의 구현이 아예 없는게 아니라 있는데 좀 큰 케이스에서 작동을 안 해서요. 최근에는 아예 C++를 버린 터라 gcc 4.x 대에서는 어떤지 모르겠습니다.

gcc 에선 생각이 잘 안나고..

1
point

Visual C++ 의 경우 O2 옵션에 전역 최적화 옵션이 포함되어 있습니다.

이를 끌 경우 inlining 은 막을 수 있습니다. 단, 성능이 20-40% 차이가 납니다.; 특히 메모리 복사가 잦거나 Memory Map File 통한 공유메모리 통신시에 차이가 많이났습니다. 물론 function depth 가 깊은 경우에도 영향을 끼쳤겠죠.

p.s. 회사에서는 STL, Boost, Template 안씁니다. 멀티 플랫폼 포팅 문제 때문에라고 들었습니다. gcc도 솔라리스 버전과 리눅스 버전이 동작이 다를 수 있다고 합니다.

그래서 어떤 분은..

1
point

callstack 대신 Binary Hex Dump값을 남긴 뒤, 이 덤프된 Binary 값을 보고 대략 어떤 함수 부분일 것이라 추측하신다고 하네요.;

아직 그 경지까지는 시도를 못해봐서..;

lifthrasiir의 이미지
7083
points

저 같은 경우

1
point

저 같은 경우 의심되는 함수에다가 __asm__ ("int $3; int $3; int $3;"); 같은 것을 넣어서 보곤 했습니다. (x86 어셈블리 얘기. int $3이 아니라 nop 같은 것도 써 봤지만 최적화하다가 사라지는 경우가 어쩌다 있더군요.) 사실 objdump만 있어도 어셈블리 아는 사람은 대강 함수 내용은 때려 찍을 수 있긴 하죠;

흑. 잘못썼군요. Retrospection -> Introspection

1
point

왠 난데없는 회고를 하고 그랬지. -_-;;

iolo의 이미지
2224
points

제일 좋은

4
points

제일 좋은 방법은...
그냥 C를 쓰시는 겁니다.
전 그냥 자바를 쓰겠습니다.

----
the smile has left your eyes...

winner의 이미지
4336
points

KIN~ 인가요? ^_^

1
point

진담이시라면 너무 냉소적이신 것 같구...
농담이시라면 유쾌하네요.

select99님이 원하시는데로 어느 정도 불붙은 것 같군요.
참고할만한 내용이 많이 나오기를...

iolo의 이미지
2224
points

KIN이라기

1
point

KIN이라기 보다는
뼈있는 농담이죠~ ㅎㅎ

----
the smile has left your eyes...

select99의 이미지
1244
points

자바쓰쎄요.. 전

1
point

자바쓰쎄요..
전 말린적없습니다.
또한님이 쓰라고 궂이 써라마라 안하셔도 전필요한것 있으면 그것씁니다 물론 자바도 예외일순 없죠...

자바의 잘못된정보가 파해쳐지는것이 두려우신건 아니신지요..

thames의 이미지
1170
points

닉네임다운 명쾌한

1
point

닉네임다운 명쾌한 답인 것 같네요~
울티마를 생각하며^^;

Scarecrow의 이미지
4376
points

이런류의 글은

1
point

이런류의 글은 언제나 속도에만 관심을 가지는 것 같습니다.
메모리 사용정도는 비교대상조차 될 수 없기 때문일까요...

select99의 이미지
1244
points

메모리나 초기 vm

1
point

메모리나 초기 vm 구동시간은 자바가 매우 불리할것같은데요..

JAVA 와 C 의 비교.

1
point

잊을만 하면 한번씩 올라와서 잼있게 해주는 주제네요.

Jave는 문법만 대충 알 고 있는 C++ 개발자로써...

한 2,3년전부터 J2EE 개발하는 프로젝트에 혼자 와서 C++ 로 이런저런거 개발중에 있습니다.

제가 옆에서 Jave 개발을 지켜보며 받은 느낌으로는 Java는 C++에 비해 느림 이상으로 느리다는겁니다.

쬐그마한 코드 최적화해서 속도 비교해보는 것 이상으로 실제 프로젝트에선 더욱 더더더 느리다는거죠.

기본적으로 메모리 사용양도 비교 자체가 안될정도로 훨씬 더 많고...
프로젝트가 커질수록 이런저런 오버헤드가 붙어서 더욱 더 느려지더군요.

OOP 적인 매력은 Java 가 멋진데... C++ 과 속도 비교할 대상은 아닌것 같습니다.

youlsa의 이미지
2644
points

역시 간만에 다시

1
point

역시 간만에 다시 한번 재미있는 떡밥이...

Java와 C의 비교는 결국 vm과 컴파일러의 실행속도 비교가 되어 버리는 경우가 많아서 큰 의미는 없다고 봅니다.

Java의 의미는 소프트웨어 작성과 유지보수 시간을 줄여준다는데 있다고 봅니다. Java가 본격적으로 쓰이기 전인 90년대 중반 미국에서는 C/C++로 작성된 프로그램들의 메모리 오류로 인해서 어마어마한 비용이 지출되고 있다는 Software Crisis에 대한 지적이 많았었던 것으로 기억합니다. 어찌보면 자바가 그런 소프트웨어 위기를 넘기는데 한 몫을 하고 있다고 보고요, C/C++ 쪽에서도 여러가지 해결책들이 나와서 결국 소프트웨어 업계 전체적으로는 긍정적으로 작용했다고 봅니다.

그리고, 근래의 비지니스 어플리케이션 소프트웨어들은 DB 중심적인 것들이 대부분이라서 사실 개발 언어의 퍼포먼스를 논하기 이전에 DB에서 충분한 실행시간을 까먹어 주기 때문에 더욱 Java가 쓸모 있는 도구가 된 것 같습니다.

물론 저는 고슬링이 재수 없다는 이유만으로도 Java가 꺼려져서 여전히 C/C++/Python/PHP 같은 것들을 주로 씁니다만... ^^

=-=-=-=-=-=-=-=-=
http://youlsa.com

소타의 이미지
4396
points

근데 지금 테스트에

1
point

근데 지금 테스트에 사용되는 저런 종류의 코드를 실무에서 사용하시는 분 계신가요?
런타임 최적화라는 것이 동적인 입력에 대해서도 항상 올바른 결과를 보장하면서도 빠른 성능을 기대할 수 있나요?
예를 들어 DB에 10만개의 랜덤값을 놓고 그걸 랜덤하게 가져와서 연산을 한다거나 할 때도 역