Swift vs Java - 加速大阵列的速度

El_*_*ppo 0 java arrays performance swift

我刚刚在填充大数组时对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)
Run Code Online (Sandbox Code Playgroud)

结果:1.66182696819305


Java的

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");
Run Code Online (Sandbox Code Playgroud)

结果:时间:3毫秒


这让我感到震惊;

  • Swift比Java快550倍......还是我使用了一些未优化的代码?

Fil*_*efp 32

你正在比较苹果和梨..

您的两个实现之间存在根本区别.

您的java实现将一次为所有300 000个元素分配内存,然后设置每个元素的值.

迅速实现将然而可能调整底层存储上的每一个迭代,因为要附加的元素,而不仅仅是将其存储在特定的位置.很可能每次迭代都不会发生旧存储的调整大小+副本,但这是可能的; 它肯定会在你的循环中不止一次发生.


我该如何解决?

要修复swift实现,您应该使用数组初始化程序在创建intArray时直接分配所需的存储,例如在下面的示例中:

var intArray = Int[](count: 300000, repeatedValue: 0)
for var i = 0; i <= 300000; ++i {
    intArray[i] = 0
}
Run Code Online (Sandbox Code Playgroud)

  • 使用*如何修复它?*部分,这个答案应该被标记为已接受的答案. (2认同)
  • 但如果目标是将数组中的每个对象初始化为特定值,[tag:swift]使用单行语句执行此操作.代码片段中的循环毫无意义. (2认同)

Dav*_* Xu 8

append 在运行时调整数组大小(每个循环!!),而您的Java代码创建一个大小为300000的数组,并只在其中设置元素.

调整大小意味着内存复制操作,而在Java代码设置中,索引是常量时间.

此外,JIT编译器可能刚刚决定你的循环是无用的,并优化了整个事情.

  • 我们确定每个循环都调整了数组的大小吗?我认为`append`的大多数实现只会在需要时调整大小,当它调整大小时,它会使当前大小加倍. (5认同)