#What did java do here for being so fast ?

25 messages · Page 1 of 1 (latest)

tribal hatch
#

So here is a simple program

import java.util.Random;

class main {

    public static void main(String[] args) {

        int MAX_VALUE = 5_000_000;
        long startTime = System.currentTimeMillis();

        Random rand = new Random();
        for (int i = 0; i < MAX_VALUE; i++) {
            eulerDistance(rand.nextInt(),rand.nextInt(),rand.nextInt(),rand.nextInt());
        }

        long endTime = System.currentTimeMillis() - startTime;

        System.out.print("Time takes: " + endTime);
    }

    static int eulerDistance(int x1, int x2, int y1, int y2) {

        return (int) Math.sqrt(
                Math.pow(((double) x2 - (double) x1), 2) +
                        Math.pow(((double) y2 - (double) y1), 2)
        );
    }


}

I just wanted to test Java vs Go speed running this, for 5 mil iterations java appx takes 0.5 seconds where as go 2-3 seconds and for 50 mil java is 2-3 seconds and didn't wait for go... was taking too long.... I know about java's JIT and have seen it speed things up but what is happening here ?? Its it skipping iterations as there is no use for the value or is it some super optimal code running ?

tiny solsticeBOT
#

<@&987246717831381062> please have a look, thanks.

pale tinsel
#

and well

#

there is a chance that java just discarded the call because the result is never used

#

also it's hard to tell if we can't see go code

tribal hatch
#

That's why

pale tinsel
tribal hatch
#

I know it can be written much better

#
package main

import (
    // "example/hello/service"
    "fmt"
    "math"
    "math/rand/v2"
    "time"
)

var globalVariable int = 20

func main() {

    var maxValue int = 5_000_0000

    var startTime int64 = time.Now().UnixMilli()

    for i := 0; i < maxValue; i++ {
        eulerDisntace(rand.Int(), rand.Int(), rand.Int(), rand.Int())
    }

    var endTime int64 = time.Now().UnixMilli() - startTime

    fmt.Printf("Time take to run: %d", endTime)

}

func eulerDisntace(x1 int, x2 int, y1 int, y2 int) int {
    return int(math.Sqrt(math.Pow(float64(x2-x1), 2) + math.Pow(float64(y2-y1), 2)))
}


tiny solsticeBOT
# tribal hatch ```go package main import ( // "example/hello/service" "fmt" "math"...

Detected code, here are some useful tools:

Formatted code
package mainimport (// "example/hello/service"
"fmt""math""math/rand/v2""time") var globalVariableint  = 20func main() {
  var maxValueint  = 5_000_0000var startTimeint 64 = time.Now().UnixMilli() for i :  = 0;


  i < maxValue;
  i++{
    eulerDisntace(rand.Int(), rand.Int(), rand.Int(), rand.Int()) }
  var endTimeint 64 = time.Now().UnixMilli() - startTime fmt.Printf("Time take to run: %d", endTime) }
func eulerDisntace(x1int , x2int , y1int , y2int ) int {
  return int (math.Sqrt(math.Pow(float 64(x2 - x1), 2) + math.Pow(float 64(y2 - y1), 2))) }
eternal geode
quasi willow
#

If no side-effects are observed from calling eulerDistance(...) JIT might decide to eliminate the call entirely

calm canopy
quasi willow
#

If the content of the loop was more predictable, you would want a sum of the distances to avoid it just finding a shortcut to computing the last one.

tribal hatch
#

Ok will sum it

stuck frigate
sand arrow
civic root
#

It is as others have said, the JIT elides the call to eulerDistance as it's return value is not held AND no state is changed in those pure functions Math.sqrt and Math.pow. rand.nextInt()'s are likely called because a seed value is updated each time for the rand object and that's the bulk of your time.

#

Also, timing this way is prone to error.

#

Only way to tell is to print compilation AFTER the JIT is warmed.

calm canopy
#

use jmh btw

#

it is made for this