【问题标题】:is fantom generated bytecode as performant as java equivalent bytecode?fantom 生成的字节码是否与 java 等效字节码一样高效?
【发布时间】:2011-04-27 08:29:45
【问题描述】:

在当今出现的许多 jvm 语言中,有一种似乎特别吸引人

看看

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

我只是想知道,当忽略动态类型功能时,生成的字节码是否与 java 的性能相当......

ps:添加了关于性能的声明

【问题讨论】:

    标签: java performance bytecode fantom


    【解决方案1】:

    我做了一些快速排序性能测试。

    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.
    

    所以我想说,目前 Fantom 的代码运行速度比 Java 的代码慢 10 倍。但是请注意,我使用了 Java 的 int 和 Fantom 的 Int,它们并不相同。 Java 的 int 是 32 位的,Fantom 的是 64 位的.

    在对事情进行了一些分析之后,有迹象表明 Fantom 代码几乎可以执行 爪哇。但是,如果性能绝对至关重要,请远离列表,使用平台特定版本的 lists 或降级到原生并使用 Java 编写。

    编辑:我和布赖恩谈过,他证实了我的怀疑。 Fantom 速度较慢的原因是因为它的所有 Int 都是 64 位整数,并且所有 Int[] 数组都类似于 ArrayList&lt;Long&gt;。新的测试显示了差异。 Fantom 仍然较慢的原因可能是它的 Duration、Int 和 List 类比普通的 ArrayListIntegerSystem.currentMillis 有更多的方法/字段。这是一个可能适合也可能不适合您的权衡。如果您真的需要高性能,只需创建一个本机方法并用 Java/C#/Javascript 对其进行编程。这样您将获得与 Java 相当的性能。

    如果您想自己测试,请参考以下来源:

    幻想来源:

    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)  
    
       }  
    }
    

    所有的 Ints 都被 longs 和 ArrayList 替换了。原始 Java 实现可以在 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);  
    
     }  
    
    }  
    

    【讨论】:

    • 我想说最终的答案是Profile it。 Fantom 可以输出.jar 文件,您可以使用任何Java profiler 来检查它。然后您可以尝试使用native 优化性能关键段。大多数情况下,它的性能与使用 ArrayList 和 Long 的 Java 相同(分别用于数组和整数)。
    • “所以我想说,目前 Fantom 的字节码比 Java 的字节码慢 10 倍。”这是不正确的。即使考虑到 Int Double 效应,您也可以从单个微基准测试中得出影响深远的结论。一个合理的结论是:有一个模糊的暗示,Fantom 几乎和 Java 一样快,但要小心 Int 列表,因为它们很慢。
    • 没错,但那是在我在下面发表评论之前写的。无论如何,事情已经解决了。感谢您指出这一点。
    【解决方案2】:

    没有使用 fantom 的经验,但看起来 fantom 解释器可以使用 java、.net 或 JS 库,但不是 fantom 编译后的字节码可以通过 java、.net 或 javascript 直接读取。

    话虽如此......我稍后会检查它,它看起来很有趣:)

    【讨论】:

    • 是的,这是真的;但是,您可以简单地强制 Fantom 输出 .jar 文件而不是 .pod(Fantom 的 .jar 模拟)。 iirc Fantom 也有 Java FFI,但没有 .Net 和 JS(它仍在开发中)。
    【解决方案3】:

    Fantom 编译成自己的字节码格式,称为“fcode” - 然后在运行时转换为 java 字节码或 IL - 请参阅此页面了解更多详细信息:

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

    JavaScript 的工作方式有点不同——实际的 JavaScript 源代码是在编译时从 Fantom 源代码生成的(以及 Fantom 运行时所需的所有元数据)——生成一个可以直接在浏览器中运行的独立 js 文件.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多