3

from the many jvm languages appearing nowdays, there's one that seems to be particularly appealing

have a look at

http://fantom.org/doc/docIntro/Tour.html

I just wonder if, when ignoring the dynamic typing feature, the generated bytecode is performant equivalent to java...

ps: added aclaration about performance

opensas
  • 52,870
  • 69
  • 227
  • 340

3 Answers3

6

I did some quicksort performance testing.

Int[100.000] array quicksort
  Java ~ 11ms
  Java using long and ArrayList<Long> ~ 66ms
  Fantom ~ 97 ms

Int[1.000.000] array quicksort
  Java ~ 91ms
  Java using long and ArrayList<long> ~ 815ms
  Fantom ~ 1100ms.

So I'd say that at the moment Fantom's code runs about 10x slower than Java's code. However do note that I used Java's int and Fantom's Int which aren't the same. Java's int are 32-bit and Fantom's are 64-bit.

After profiling things a bit there are indications that Fantom code is almost performant as Java. However if performance is absolutely critical, stay away from Lists, use platform specific versions of lists or drop down to native and write in Java.

EDIT: I had a talk with brian and he confirmed my suspicions. The reason Fantom is slower is because all it's Int are 64-bit integer and all Int[] arrays are similar to ArrayList<Long>. The new test show the difference. The reason Fantom is still slower is probably that its Duration, Int and List classes have a lot more methods/fields than plain ArrayList or Integer or System.currentMillis. It's a tradeoff that may or may not suit you. If you really need high performance just make a native method and program it in Java/C#/Javascript. That way you'll get Java equivalent performance.

Here are sources if you want to test it yourself:

Fantom source:

class TestQuickSort
{

   public static Void swap(Int[] a, Int i, Int j) {  
    temp := a[i];  
    a[i] = a[j];  
    a[j] = temp;  
   }  

   public static Void quicksortA(Int[] a, Int L, Int R) {  
    m := a[(L + R) / 2];  
    i := L;  
    j := R;  
    while (i <= j) {  
     while (a[i] < m)  
      i++;  
     while (a[j] > m)  
      j--;  
     if (i <= j) {  
      swap(a, i, j);  
      i++;  
      j--;  
     }  
    }  
    if (L < j)  
     quicksortA(a, L, j);  
    if (R > i)  
     quicksortA(a, i, R);  
   }  

   public static Void quicksort(Int[] a) {  
    quicksortA(a, 0, a.size - 1);  
   }   

  static Void main(Str[] args) {  

    // Sample data  
    a := Int[,]

    for(i := 0; i<1000000; i++)
    {
      a.add(i*3/2+1)
      if(i%3==0) {a[i]=-a[i]}
    }

    t1 := Duration.now 
    quicksort(a);  
    t2 := Duration.now 
    echo((t2-t1).toMillis)  

   }  
}

And java with all the Ints replaced by longs and ArrayList. Original Java implementation can be found at http://stronglytypedblog.blogspot.com/2009/07/java-vs-scala-vs-groovy-performance.html.

import java.util.ArrayList;
public class QuicksortJava {  

 public static void swap(ArrayList<Long> a, long i, long j) {  
  long temp = a.get((int)i);  
  a.set((int)i, a.get((int)j));  
  a.set((int)j, temp);  
 }  

 public static void quicksort(ArrayList<Long> a, long L, long R) {  
  long m = a.get((int)(L + R) / 2);  
  long i =  L;  
  long j =  R;  
  while (i <= j) {  
   while (a.get((int)i) < m)  
    i++;  
   while (a.get((int)j) > m)  
    j--;  
   if (i <= j) {  
    swap(a, i, j);  
    i++;  
    j--;  
   }  
  }  
  if (L < j)  
   quicksort(a, L, j);  
  if (R > i)  
   quicksort(a, i, R);  
 }  

 public static void quicksort(ArrayList<Long> a) {  
  quicksort(a, 0, a.size() - 1);  
 }  

 public static void main(String[] args) {  

  // Sample data  
  long size = 100000;
  ArrayList<Long> a = new ArrayList<Long>((int)size);  
  for (long i = 0; i < size; i++) {  
   a.add(i * 3 / 2 + 1);  
   if (i % 3 == 0)  
    a.set((int)i, -a.get((int)i));  
  }  

  long t1 = System.currentTimeMillis();  
  quicksort(a);  
  long t2 = System.currentTimeMillis();  
  System.out.println(t2 - t1);  

 }  

}  
Daniel Fath
  • 11,537
  • 6
  • 39
  • 72
  • 2
    I'd say ultimate answer would be **Profile it**. Fantom can output `.jar` files and you can use any Java profiler to examine it. Then you could try to optimize performance critical segments with `native`. Most of the time it has same performance as Java using ArrayList and Long (for arrays and integers respectively). – Daniel Fath Jul 01 '11 at 13:55
  • "So I'd say that at the moment Fantom's bytecode runs about 10x slower than Java's bytecode." This is just incorrect. You draw much to far-reaching conclusions from a single micro benchmark, even considering the Int Double effect. A reasonable conclusion would be: There is a vague hint that Fantom is almost as fast as Java, but beware of List of Int becase they are slow. – Lii Apr 08 '12 at 13:35
  • True, but that was written before I made my remark below. Anyway the thing has been fixed. Thanks for pointing that out. – Daniel Fath Apr 10 '12 at 15:11
2

I have no experience with fantom, but it looks like the fantom interpreter can use java, .net or JS libraries, but it's not that the fantom compiled bytecode can be read out of the box by java, .net or javascript.

Having said that... I'll check it later, it looks interesting :)

Augusto
  • 26,525
  • 5
  • 52
  • 82
  • Yes, that is true; However you can simply force Fantom to output `.jar` file instead of a `.pod` (Fantom's `.jar` analogue). Also iirc Fantom has Java FFI but not .Net and JS (it's still in development). – Daniel Fath Jul 02 '11 at 11:16
2

Fantom compiles down to its own byte-code format called "fcode" - which is then translated to java byte code or IL at runtime - see this page for more details:

http://fantom.org/doc/docLang/Deployment.html

JavaScript works a bit different - actual JavaScript source code is produced at compile time from the Fantom source code (along with all the meta-data the Fantom runtime needs) - to produce a standalone js file you can run directly in your browser.

afrankvt
  • 181
  • 3