konsoletyper / teavm

Compiles Java bytecode to JavaScript, WebAssembly and C
https://teavm.org
Apache License 2.0
2.62k stars 262 forks source link

JS native Integer.toString #768

Open Ihromant opened 1 year ago

Ihromant commented 1 year ago

Performance test:

public static void main(String[] args) {
        int[] integers = new int[1_000_000];
        int sink = 0;
        fill(integers, ThreadLocalRandom.current()::nextInt);
        for (int i : integers) {
            sink += Integer.toString(i).length();
        }
        System.out.println("Warmup: " + sink);
        fill(integers, ThreadLocalRandom.current()::nextInt);
        long time = System.currentTimeMillis();
        for (int i : integers) {
            sink += Integer.toString(i).length();
        }
        System.out.println("Mixed integers: " + (System.currentTimeMillis() - time) + ", sink: " + sink);
        fill(integers, () -> ThreadLocalRandom.current().nextInt(-99, 100));
        time = System.currentTimeMillis();
        for (int i : integers) {
            sink += Integer.toString(i).length();
        }
        System.out.println("Small integers: " + (System.currentTimeMillis() - time) + ", sink: " + sink);
        fill(integers, () -> ThreadLocalRandom.current().nextBoolean()
                ? ThreadLocalRandom.current().nextInt(Integer.MIN_VALUE, -100_000_000)
                : ThreadLocalRandom.current().nextInt(100_000_000, Integer.MAX_VALUE));
        time = System.currentTimeMillis();
        for (int i : integers) {
            sink += Integer.toString(i).length();
        }
        System.out.println("Large integers: " + (System.currentTimeMillis() - time) + ", sink: " + sink);
        fill(integers, ThreadLocalRandom.current()::nextInt);
        time = System.currentTimeMillis();
        for (int i = 0; i < integers.length; i++) {
            int val = integers[i];
            sink += Integer.toString(val, i % 30 + 2).length();
        }
        System.out.println("Integers with radix: " + (System.currentTimeMillis() - time) + ", sink: " + sink);
    }

    private static void fill(int[] values, IntSupplier generator) {
        for (int i = 0; i < values.length; i++) {
            values[i] = generator.getAsInt();
        }
    }

Also code is shorter by 200 bytes. :D Results: |Browser|old mixed|new mixed|old short|new short| |Chromium|841,871,874|821,879,844|843,829,828|686,686,679| |Firefox|749,729,735|624,642,624|680,672,663|619,623,596|

|Browser|old long|new long|old radix|new radix| |Chromium|901,874,871|843,757,808|896,878,877|894,908,891| |Firefox|744,720,716|612,635,625|788,778,761|635,667,664| According to results, it's small, but still performance improvement in firefox everywhere. In Chrome it's not-degrading change which is also improvement for small integers.