Golang has many advantages over Java such as simple syntax, microservice compatibility, lightweight threads, and fast performance. But are there any areas where Java is superior to Go? In which cases would you prefer to use Java instead of Go?
Reasons you prefer Golang over Java?
go - Speed of Golang Vs Java - Stack Overflow
What are your thoughts after moving from Java to Go
Go vs Java
What is better than Golang?
Node.js is a language that can easily compete with Golang and has a far larger community and more supporting tools.
Is Java still worth learning?
Very much so. If you’re building mobile applications, web apps, or have to integrate with AI applications or IoT devices, Java could very well be your best bet.
Videos
Background: I've been using Java for about 8 years and just started learning Golang.
So far, I'm in love with the language, and these are the top reasons:
More low-level control of memory. I hated how much the JVM's GC relied on the compactor. Objects can only be created on the heap and object arrays are arrays of pointers to non-contiguous locations in memory. Many like to say that Java has better GCs than Go, but that's because Go's memory model doesn't require such complicated GCs. It's also nice to have pointers in Go.
More paradigm-neutral. Java was designed from the beginning to be a language primarily for OO programming. Using Java for functional programming results in unnatural syntax and inefficient use of memory. Golang feels ambidextrous.
I'm still very new to Golang but as of right now, I even see it as a replacement for Node and Python in the areas of scripting and web server development. Golang's fast compile time closes makes it competitive against interpreted languages in terms of development speed, but 1-ups these languages because it gives the developer more low-level control of memory and has static typing.
(With tips from above answers, I did more test, with an additional C and V version)
On my Linux machine, with times = 100000000.
Testing result:
- When exponent = 2.4
Copy Java: result: 1.053906e+24, during: 7432 ms
C: result: 1.053906e+24, during: 5544 ms
Go: result: 1.053906e+24, during: 8.716807708s
V: result: 1.053906e+24, during: 2.342s
- When exponent = 2, still use
pow()orPow().
Copy Java: result: 1.543194e+21, during: 630 ms
C: result: 1.543194e+21, during: 852 ms
Go: result: 1.543194e+21, during: 3.336549272s
V: result: 1.543194e+21, during: 128.160ms
- When exponent = 2, but use
x * xinstead.
Copy Java: result: 1.543194e+21, during: 636 ms
C: result: 1.543194e+21, during: 340 ms
Go: result: 1.543194e+21, during: 115.491272ms
V: result: 1.543194e+21, during: 122.283ms
Summary:
- In general, Go is really fast, according to the last test, faster than Java, or even C.
- But, Java really has a good
pow()implementation, according to the first two tests. - V, a new language similar to Go in some way, is very fast.
Code
Test.java:
Copy/**
* Compile:
* javac Test.java
* Run:
* java Test
*/
public class Test {
public static void main(String[] args) {
Test test = new Test();
long startAt = System.currentTimeMillis();
double re = test.testFun(10, 16666611, 100000000);
long during = System.currentTimeMillis() - startAt;
System.out.printf("%10s: result: %e, during: %d ms\n", "Java", re, during);
}
private double testFun(double first, double second, long times) {
int i = 0;
double result = 0;
double dx = (second - first) / times;
for (; i < times; i++) {
result += fun(first + i * dx);
}
return result * dx;
}
private double fun(double v) {
return v * v - v;
// return Math.pow(v, 2) - v;
// return Math.pow(v, 2.4) - v;
}
}
test.c:
Copy/**
* compile with:
* gcc test.c -lm
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
double fun(double v) {
return v * v - v;
// return pow(v, 2) - v;
// return pow(v, 2.4) - v;
}
double testFun(double first, double second, long times) {
int i;
double result = 0;
double dx = (second - first) / times;
for (i = 0; i < times; i++) {
result += fun(first + i * dx);
}
return result * dx;
}
long long current_timestamp() {
struct timeval te;
gettimeofday(&te, NULL); // get current time
long long milliseconds =
te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds
// printf("milliseconds: %lld\n", milliseconds);
return milliseconds;
}
int main(int argc, char *argv[]) {
long long startAt = current_timestamp();
double re = testFun(10, 16666611, 100000000);
long long during = current_timestamp() - startAt;
printf("%10s: result: %e, during: %lld ms\n", "C", re, during);
return 0;
}
test.go:
Copy/**
* How to run:
* go run test.go
*/
package main
import (
"fmt"
"math"
"time"
)
func main() {
startAt := time.Now()
result := testFun(10, 16666611, 100000000)
during := time.Since(startAt)
fmt.Printf("%10s: result: %e, during: %v\n", "Go", result, during)
_ = math.Pow
}
func fun(x float64) float64 {
return x*x - x
// return math.Pow(x, 2) - x
// return math.Pow(x, 2.4) - x
}
func testFun(first float64, second float64, times int) float64 {
var i = 0
var result float64 = 0
var dx float64
dx = (second - first) / float64(times)
for ; i < times; i++ {
result += fun(first + float64(i)*dx)
}
return result * dx
}
speed_v.v:
Copyimport time
import math
// compile & run with: v -prod crun speed_v.v
fn main() {
lang := 'V'
start_at := time.now()
result := run_fun(10, 16666611, 100000000)
during := time.since(start_at)
println('${lang}: result: ${result:.7}, during: ${during}')
}
fn fun(x f64) f64 {
// return x * x - x
return math.pow(x, 2) - x
// return math.pow(x, 2.4) - x
}
fn run_fun(first f64, second f64, times int) f64 {
mut i := 0
mut result := 0.0
dx := (second - first) / times
for ; i < times; i++ {
result += fun(first + i * dx)
}
return result * dx
}
Compile:
Copyjavac Test.java; gcc test.c -lm; go build test.go; v -prod speed_v.v
Run:
Copyjava Test; ./a.out ; ./test; ./speed_v
@Update - C program with -O2 or -O3 option
As suggested by Raffaello in the comment, when compiling C program, could use -O2 or -O3 to further optimize the program.
And, following are the test result for the C program:
- When exponent = 2.4.
Copy C: result: 1.543194e+21, during: 5805 ms
C with `-O2`: result: 1.543194e+21, during: 5324 ms
C with `-O3`: result: 1.543194e+21, during: 5326 ms
- When exponent = 2, still use
pow()orPow().
Copy C: result: 1.543194e+21, during: 897 ms
C with `-O2`: result: 1.543194e+21, during: 119 ms
C with `-O3`: result: 1.543194e+21, during: 121 ms
- When exponent = 2, but use
x * xinstead.
Copy C: result: 1.543194e+21, during: 353 ms
C with `-O2`: result: 1.543194e+21, during: 122 ms
C with `-O3`: result: 1.543194e+21, during: 119 ms
Summary - (-O2 and -O3 option):
- With
-O2and-O3option- When base is integer (e.g 2), would make c program quicker, by several times.
- When base is floating point number (e.g 2.4), it's also quicker, but very minimal.
- Comparing between
-O2and-O3, they are quite close in above tests.
Don't translate from another language. Write the Go version of your program in Go. For example, x*x - x,
Copypackage main
import (
"fmt"
"math"
"time"
)
func main() {
start := time.Now()
v := testFun(10, 16666611, 1000000000)
since := time.Since(start)
fmt.Printf("value is %v\ntime is %v\n", v, since)
}
func fun(x float64) float64 {
return x*x - x
}
func testFun(first float64, second float64, times int) float64 {
sum := float64(0)
dx := (second - first) / float64(times)
for i := 0; i < times; i++ {
sum += fun(first + float64(i)*dx)
}
return sum * dx
}
Output:
Copy$ go version
go version devel +5c11480631 Fri Aug 10 20:02:31 2018 +0000 linux/amd64
$ go run speed.go
value is 1.543194272428967e+21
time is 1.011965238s
$
What results do you get?