DEV Community

Cover image for "Hello World" performance comparison between GraalVM and Go
Theofanis Despoudis
Theofanis Despoudis

Posted on

"Hello World" performance comparison between GraalVM and Go

Go is an established language with a lots of production exposure. Go is infamous for creating small application footprint and fast performance.

As for GraalVM, taken from their Website:

GraalVM is a universal virtual machine for running applications written in JavaScript, Python, Ruby, R, JVM-based languages like Java, Scala, Groovy, Kotlin, Clojure, and LLVM-based languages such as C and C++.

Which means that it combines the JVM ecosystem with the small footprint and performance of native apps. It looks very promising so far.

In this tutorial I wanted to check really quick what is their "Hello World" performance characteristics just to see how the compare. I may be doing more experiments with different apps to explore more about it.

The Program

I've used standard hello world programs for both Kotlin and Go:

package main

import "fmt"

func main() {
    fmt.Println("hello world")
}
Enter fullscreen mode Exit fullscreen mode
package hello

fun main(args: Array<String>) : Unit {
    println("Hello world")
}
Enter fullscreen mode Exit fullscreen mode

I've used the following versions for Go and GraalVM native-image utility:

$ go version      
go version go1.12.9 darwin/amd64

Enter fullscreen mode Exit fullscreen mode
$GRAALVM_HOME/bin/native-image --version 
GraalVM Version 19.3.0 CE
Enter fullscreen mode Exit fullscreen mode

I run the examples in this following system:

  Model Name:   MacBook Pro
  Model Identifier: MacBookPro12,1
  Processor Name:   Intel Core i5
  Processor Speed:  2.9 GHz
  Number of Processors: 1
  Total Number of Cores:    2
  L2 Cache (per Core):  256 KB
  L3 Cache: 3 MB
  Hyper-Threading Technology:   Enabled
  Memory:   16 GB
Enter fullscreen mode Exit fullscreen mode

The Results

First I compiled the Go executable:

$ go build main.go
Enter fullscreen mode Exit fullscreen mode

Disk usage reports only 2mb! Thats great:

$ du -h  main                    
2.0M    main

Enter fullscreen mode Exit fullscreen mode

Time usage via both time and gnu-time commands:

$ gtime -v ./main
hello world
        Command being timed: "./main"
        User time (seconds): 0.00
        System time (seconds): 0.00
        Percent of CPU this job got: 66%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 1960
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 615
        Voluntary context switches: 1
        Involuntary context switches: 75
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0


$ time ./main          
hello world
./main  0.00s user 0.00s system 60% cpu 0.010 total

Enter fullscreen mode Exit fullscreen mode

Next I compiled the Kotlin example:

I run maven install typically and then the native-image tool:

mvn clean install

$GRAALVM_HOME/bin/native-image -cp ./target/mixed-code-hello-world-1.0-SNAPSHOT.jar -H:Name=helloworld -H:Class=hello.JavaHello -H:+ReportUnsupportedElementsAtRuntime --allow-incomplete-classpath

Enter fullscreen mode Exit fullscreen mode

Disk usage reports 2.8mb! Not bad:

$ du -h ./helloworld 
2.8M    ./helloworld

Enter fullscreen mode Exit fullscreen mode

Time usage via both time and gnu-time commands:

$ gtime -v ./helloworld
Hello world
        Command being timed: "./helloworld"
        User time (seconds): 0.00
        System time (seconds): 0.00
        Percent of CPU this job got: 57%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 2072
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 657
        Voluntary context switches: 0
        Involuntary context switches: 11
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0


$ time ./helloworld
Hello world
./helloworld  0.00s user 0.00s system 56% cpu 0.006 total

Enter fullscreen mode Exit fullscreen mode

Looking at the results, they almost look comparable but of course this is just a simplified example and does not show a lot of info. I will certainly explore more of the examples given by the GraalVM team.

Let me know what you think.

Top comments (4)

Collapse
 
maartyl profile image
maartyl

Thank you for informing me about the existence of GraalVM. I've never heard about it.

The binary size comparison is interesting.

As for measuring time: Doing it once is useless. The rest of the system surely impacted those times more than the programs themselves. Also, they are so tiny, they have no informative value. - All we know is that it does not start a runtime VM, that would take as long as JVM to start.

A more interesting "hello world" benchmark would be maybe something like: allocating a few hundred thousand objects and sorting them - repeating 50 times, or so.

Collapse
 
kgignatyev profile image
Konstantin Ignatyev

Just for fun I have implemented a decent utility in Java, Rust, Go, and then modified Java version to be compile it to native image. Surprisingly: Java based native image outperformed even Rust version. I suspect that it can be attributed to high quality implementation of JSON parser. 93ms vs 125ms

github.com/kgignatyev/hiera-ctp

Collapse
 
theodesp profile image
Theofanis Despoudis

Feel free to try it out.

Collapse
 
ozkanpakdil profile image
özkan pakdil

both are 2mb I was expecting far more smaller from golang :) I am starting to think graalvm started to just match golang :)

but I must say java still looks nicer to me as language.