-2

So I have 2 programs that do the same things, one written in C and the other in Java. They both create 50 threads and wait for all of them to finish, then terminates.

In order to get a feel for the time difference between the 2 programs, I used the 'time' command in Linux to get the execution time.

For the C program, total execution time was 0.020 seconds, while it took the Java version 0.663 seconds to complete.

I've tried searching for an answer but all I've found were some articles such as (these two ) saying that Java was actually faster than C, which I thought was nonsense, so I would really appreciate if anyone could clarify this for me.

Thanks.

This is what the C code looks like.

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#define N 50

void* tproc(void *arg) {
    printf("Thread %d\n", *((int *) arg));
    return NULL;
}

int main(int argc, char * argv[]) {
    int i;
    int targ[N];
    pthread_t tid[N];
    for(i = 0; i < N; i++) {
    targ[i] = i;
        if(pthread_create(&(tid[i]), NULL, &tproc, &targ[i]) != 0) {
            printf("Can't create thread %d\n", i);
            return 1;
        }
    }
    for(i = 0; i < N; i++) {
        if(pthread_join(tid[i], NULL) != 0) {
            printf("Can't join thread %d\n", i);
        }
    }
    return 0;
}

This is what the Java code looks like.

import java.util.concurrent.*;

class MyThread extends Thread {

    static final int N = 50 ;
    int arg;

    public MyThread(int arg) {
        this.arg = arg;
    }

    public void run() {
       System.out.println("Thread " + arg);
    }

    public static void main(String [] args) {
        MyThread[] tid = new MyThread [N] ;
        for(int i = N-1; i >= 0; i--) {
            tid[i] = new MyThread(i);
            tid[i].start();
        }
        for(int i = 0; i < N; i++) {
            try { tid[i].join(); }
            catch(InterruptedException e) { }
        }
    }
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • 1
    Because Java is an interpreted language. – S.S. Anne Oct 15 '19 at 11:29
  • @JL2210 Could you elaborate on that, please? – Cristian Anghel Oct 15 '19 at 11:29
  • 3
    Java compiles to bytecode that is interpreted. C compiles to machine-code that is sent directly to the processor. – S.S. Anne Oct 15 '19 at 11:30
  • 1
    I dont think so. Aren't all language implementation of the same machine code. – papaya Oct 15 '19 at 11:31
  • 4
    @CristianAnghel: try timing a Java program that does absolutely nothing (i.e. empty `main`). JVM startup itself can be quite expensive. – Mat Oct 15 '19 at 11:32
  • 1
    Please [edit] your question and show some links to articles that state that Java is actually faster than C. – Jabberwocky Oct 15 '19 at 11:33
  • Please find the answer in the link : https://stackoverflow.com/questions/29662971/java-faster-than-c – Shivendra Pratap Kushwaha Oct 15 '19 at 11:34
  • 1
    lets compare which is faster: a motorcycle or a car... actually I can have a bicycle that is faster than a car (under specific conditions) – user85421 Oct 15 '19 at 11:45
  • The best way to answer your question in general is to recognize that software speed performance has much more to do with the programmer, and program design than it does with the language used to implement. ( _[this is not a new idea](https://softwareengineering.stackexchange.com/a/110642/143513)_. ) – ryyker Oct 15 '19 at 12:22
  • Also see: [How to write a correct micro-benchmark](https://stackoverflow.com/q/504103/5699679) – Avi Oct 15 '19 at 12:59

4 Answers4

7

Add some profiling/time measurement to know for sure. For instance, add a timer inside your code, to measure how long does main take to run. And run the test many times, as CPU time of a process can vary a lot from execution to execution (because of whatever else the OS is doing, etc)

C programs are compiled to native machine code, closely related to assembly. That means, that the program gets compiled (pretty much) to individual instructions that the CPU already knows how to execute.

Java programs are usually compiled to intermediate bytecode, not to native machine code. The CPU won't (most likely) know how to run these instructions. Running a Java program involves starting the JVM, which will translate these bytecode instructions to native machine code, and then they will be executed by the CPU. This step of loading the JVM and translating the code takes extra time, that's outside of your 'main' function running.

Also to be taken into account is that Java has a garbage collector that, among other things, protects against resource leaks. C lacks this, which means you have to manage resources yourself. The Java garbage collector also takes time to start and may incur a CPU time overhead during execution, depending on the program.

There are other low level and high level considerations here, but this is just for starters...

ArthurChamz
  • 2,039
  • 14
  • 25
4

Because a Java Program (actually it's the compiled binary, a.k.a. bytecode) is running on top of a virtual machine named JVM, while native binaries (e.g., in your wording, C program) are running on bare metal. The JVM will do quite a little work to enable the virtual "instructions" run a bare metal, e.g., interpretation as a primitive and naive implementation, JIT as a more sophisticated measure. Besides, the automatic memory management mechanism named garbage collection (GC) will slow down the virtual machine significantly when your application is memory allocation intensive. If you are interested in the JVM specification, please learn more from https://docs.oracle.com/javase/specs/jvms/se7/html/

tibetty
  • 563
  • 2
  • 10
  • Please allow me to correct my saying a little: it's not necessarily a real bare metal, a h/w competent VM managed by hypervisor is also a real world case. – tibetty Oct 15 '19 at 12:57
2

Another possible reason is that when you launch java you need to load all the runtime into memory.

Maybe try instrumenting your code to measure the actual running time of the code and not that of the execution of the whole command and you might see different results.

It is likely C will still be faster as Java bytecode is interpreted at the beginning. However, with very long loops, at some time, the just-in-time (JIT) compiler might kick in and probably performance may become similar to that of a compiled language.

Other reason Java can sometimes be faster than C: in programs with dynamic allocation of lots of data structures, Java's garbage collector will usually collect whole batches of objects together, thus optimizing the time needed to free memory. On the other hand, in C, you have to call free manually, destructing one object at a time. This is both a good thing since you control when it happens, and a bad thing since the kind of optimization I mentioned is had to come up with (also automatic garbage collection is good because it will prevent many memory leaks anyway).

ADegorre
  • 41
  • 5
1

Several reasons:

  1. Compiled C code (typically) runs natively, whereas compiled Java code (typically) runs in a virtual machine (basically a machine-code-level interpreter) - all things being equal, native code will run faster than code in a VM;

  2. Compiled Java code performs a number of run-time checks that compiled C code does not (array bounds checks, null pointer checks, etc);

  3. The Java virtual machine performs periodic garbage collection of heap-allocated objects that are no longer being used - C doesn't do any kind of automated memory management at all;

John Bode
  • 119,563
  • 19
  • 122
  • 198