我进行了一些快速排序的性能测试。
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代码的性能几乎与Java一样好。但是如果性能绝对关键,请避免使用Lists,使用平台特定版本的lists或降级到本机,并编写Java代码。
编辑:我与Brian进行了谈话,他证实了我的怀疑。Fantom较慢的原因是因为所有的Int
都是64位整数,而所有的Int[]
数组类似于ArrayList<Long>
。新的测试显示了差异。Fantom仍然较慢的原因可能是它的Duration、Int和List类具有比普通的ArrayList
、Integer
或System.currentMillis
更多的方法/字段。这是一个可能适合您的权衡。如果您真的需要高性能,只需创建一个本地方法并在Java/C#/Javascript中编程。这样您将获得与Java相当的性能。
如果您想要自行测试,以下是源代码:
Fantom源代码:
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)
}
}
在所有的int类型和ArrayList中替换为long类型后,Java的性能将得到提升。原始的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);
}
}
我对fantom没有经验,但看起来fantom解释器可以使用Java、.NET或JS库,但是fantom编译后的字节码不能直接被Java、.NET或JavaScript读取。
话虽如此……我稍后会检查一下,这看起来很有趣 :)
.jar
文件而不是.pod
(Fantom的.jar
类似物)。另外,如果我没记错的话,Fantom有Java FFI,但没有.NET和JS(仍在开发中)。 - Daniel FathFantom编译成自己的字节码格式,称为"fcode",然后在运行时将其转换为Java字节码或IL - 更多细节请参见此页面:
http://fantom.org/doc/docLang/Deployment.html
JavaScript的处理方式略有不同 - 在编译时,实际的JavaScript源代码从Fantom源代码中生成(以及Fantom运行时所需的所有元数据)- 产生一个独立的js文件,您可以直接在浏览器中运行。
.jar
文件,您可以使用任何Java分析器来检查它。然后,您可以尝试使用native
优化关键性能段。大多数情况下,它与使用ArrayList和Long(分别用于数组和整数)的Java具有相同的性能。 - Daniel Fath