I've been doing some experiments with lists lately. Generally, Fantom performance is similiar to Java which I consider very good. I also found some oddities. Let's say this sample
class Main
{
static Void main(Str[] args)
{
iterations := 10000000
Int[] x := List(Int#, 16).fill(0, 16)
startTime := DateTime.now
for (Int i := 0; i < iterations; i++)
{
clear(x)
}
elapsed := DateTime.now(null) - startTime
echo("x${x[10]}")
echo("Elapsed: $elapsed, ${iterations * 1000 / elapsed.toMillis} req/s")
}
private static Void clear(Int[] x) {
for (Int i := 0; i < 16; i++)
{
x[i] = 0
}
}
}
On my computer it finishes in about 1100ms. If written in Java using comparable ArrayList I get a similar number
import java.util.List;
import java.util.ArrayList;
public class test {
public static void main(String args[]) throws Exception{
long iterations = 10000000;
List x = new ArrayList(16);
for (int i = 0; i < 16; i++) {
x.add(i, 0);
}
long start = System.currentTimeMillis();
for (long i = 0; i < iterations; i++)
{
clear(x);
}
long elapsed = System.currentTimeMillis() - start;
System.out.println("x=" + x.get(10));
System.out.println("Elapsed: " + elapsed + "ms, " + (iterations * 1000 / elapsed) + " req/s");
}
private static void clear(List x) {
for (int i = 0; i < 16; i++) {
x.set(i, new Integer(111));
//x.set(i, 111); // Using this is 5x faster
}
}
}
this code finishes in about 1000ms too. However rewriting list set to plain x.set(i, 111) speeds things considerably and the whole program ends in approximately 200ms.
I tried to run javap on resulting classes but for some reason I obtained completely same output for both java versions. Any ideas what optimization is used there and whether we could use it for Fantom too?
tcolarSun 28 Mar 2010
Wouldn't creating all those integer objects slow it down.
if you create a constant to hold the Integer of value 111, rather than creating a new one each time, i would expect similar performance then.
Other than that maybe it could be do to autoboxing, but probably not since java collections uses objects types(no primitives) if i recall correctly
brianMon 29 Mar 2010
Fantom boxes Int using Long.valueOf which hopefully long term will be a signal for HotSpot optimization (especially if a constant is passed).
Although sometimes it is pretty difficult to track down why HotSpot optimizes a specific body of code better than others. I believe there is an option to dump the raw x86 assembly instructions when you really want to dig into it.
katoxMon 29 Mar 2010
I tried a different tool for bytecode inspection and after a few tests it seems that the slowdown is actually when invokestatic is changed to invokespecial.
Changing the iterator from int to Integer (forcing compareTo) slows down the code to 1/2, changing inner number to Integer introduces autoboxing intValue call -- then the speed is more or less equivalent to Fantom version.
So it might be beneficial to detect trivial loops and generate primitive iterators. In short term, what would you say about a facet hinting the compiler to generate such code directly (like @MinValue/@MaxValue)?
Note: I found these docs OpenJDK7 and this blog Special debug version of JDK6. I'll try those, thanks for pointing that out - I wasn't aware of that possibility.
katox Sun 28 Mar 2010
I've been doing some experiments with lists lately. Generally, Fantom performance is similiar to Java which I consider very good. I also found some oddities. Let's say this sample
On my computer it finishes in about 1100ms. If written in Java using comparable
ArrayList
I get a similar numberthis code finishes in about 1000ms too. However rewriting list set to plain
x.set(i, 111)
speeds things considerably and the whole program ends in approximately 200ms.I tried to run
javap
on resulting classes but for some reason I obtained completely same output for both java versions. Any ideas what optimization is used there and whether we could use it for Fantom too?tcolar Sun 28 Mar 2010
Wouldn't creating all those integer objects slow it down.
if you create a constant to hold the Integer of value 111, rather than creating a new one each time, i would expect similar performance then.
Other than that maybe it could be do to autoboxing, but probably not since java collections uses objects types(no primitives) if i recall correctly
brian Mon 29 Mar 2010
Fantom boxes Int using
Long.valueOf
which hopefully long term will be a signal for HotSpot optimization (especially if a constant is passed).Although sometimes it is pretty difficult to track down why HotSpot optimizes a specific body of code better than others. I believe there is an option to dump the raw x86 assembly instructions when you really want to dig into it.
katox Mon 29 Mar 2010
I tried a different tool for bytecode inspection and after a few tests it seems that the slowdown is actually when
invokestatic
is changed toinvokespecial
.Changing the iterator from
int
to Integer (forcingcompareTo
) slows down the code to 1/2, changing inner number to Integer introduces autoboxingintValue
call -- then the speed is more or less equivalent to Fantom version.So it might be beneficial to detect trivial loops and generate primitive iterators. In short term, what would you say about a facet hinting the compiler to generate such code directly (like @MinValue/@MaxValue)?
Note: I found these docs OpenJDK7 and this blog Special debug version of JDK6. I'll try those, thanks for pointing that out - I wasn't aware of that possibility.