我刚刚在填充大数组时对Java和Swift进行了一次小的速度比较。 我想出了以下结果:
import Foundation
let start = CFAbsoluteTimeGetCurrent()
var intArray = Int[]()
for var i = 0; i <= 300000; ++i {
intArray.append(0)
}
let timeTaken = CFAbsoluteTimeGetCurrent() - start
println(timeTaken)
结果:1.66182696819305
long start = System.currentTimeMillis();
int[] intArray;
int i = 0;
intArray = new int[300000];
for (i = 0; i < 300000; i++) {
intArray[i]=0;
}
System.out.println("Time: "+(System.currentTimeMillis()-start)+"ms");
结果:时间:3毫秒
这让我感到震惊;
答案 0 :(得分:32)
两种实现之间存在根本区别。
您的 java 实现将一次为所有 300 000 元素分配内存,然后设置每个元素的值。
然后 swift 实现可能在每次迭代时调整基础存储的大小,因为您要附加一个元素,而不仅仅是将其存储在特定的位置。很可能每次迭代都不会发生旧存储的调整大小+副本,但这是可能的;它肯定会在你的循环中不止一次发生。
要修复 swift 实现,您应该使用array-initializer在创建 intArray 时直接分配所需的存储,如下例所示:
var intArray = Int[](count: 300000, repeatedValue: 0)
for var i = 0; i <= 300000; ++i {
intArray[i] = 0
}
答案 1 :(得分:8)
append
在运行时调整数组的大小(每个循环!!),而你的Java代码创建一个大小为300000的数组,并只在其中设置元素。
调整大小意味着内存复制操作,而在Java代码设置中,索引是常量时间。
另外,JIT编译器可能刚刚决定你的循环没用,并优化了整个过程。
答案 2 :(得分:1)
我意识到这已经很老了,但我随机遇到了它而DuckDucking因为一些无关的东西,我想我会提供一些......更新。
首先,现在Swift中的语法与FilipRoséen的回答完全不同。例如,没有更多C风格的循环。在编译器上也做了一些工作。
就像之前的答案解释一样,您正在比较两种不同的东西(增长数组与初始化数组)。但是,由于各种变化,Swift现在大大快了。
请原谅我的Java代码,如果它不是最理想的;这几乎是我第一次写Java。
这是我用来动态增长数组的代码:
爪哇:
import java.util.List;
import java.util.ArrayList;
public class java_GrowArray {
public static void main(String[] args) {
long start = System.nanoTime();
List<Integer> intArray = new ArrayList<Integer>();
for (int i = 0; i < 300000; i++) {
intArray.add(0);
}
System.out.println("Time: "+(float)(System.nanoTime()-start)/1000000000 +" s");
}
}
夫特:
import Foundation
let start = CFAbsoluteTimeGetCurrent()
var intArray: [Int] = []
for _ in 0..<300000 {
intArray.append(0)
}
let timeTaken = CFAbsoluteTimeGetCurrent() - start
print("Time: \(timeTaken) s")
以下是刚刚初始化固定大小数组的代码:
爪哇:
public class java_InitialiseArray {
public static void main(String[] args) {
long start = System.nanoTime();
int[] intArray;
int i = 0;
intArray = new int[300000];
for (i = 0; i < 300000; i++) {
intArray[i]=0;
}
System.out.println("Time: "+(float)(System.nanoTime()-start)/1000000000 +" s");
}
}
夫特:
import Foundation
let start = CFAbsoluteTimeGetCurrent()
let intArray = [Int](repeating: 0, count: 300000)
let timeTaken = CFAbsoluteTimeGetCurrent() - start
print("Time: \(timeTaken) s")
计时(每次运行五次中位数):
Grow array (Java): 0.01376 s
Grow array (Swift): 0.01035 s
Init array (Java): 0.00448 s
Init array (Swift): 0.00181 s
显然,Swift的性能行为与2018年相比在几年前有很大差异。