【发布时间】:2014-08-20 01:06:57
【问题描述】:
我在 Swift 中使用 Dictionary 来实现本质上是缓存的东西。性能远远低于我的预期。我已经阅读了其他一些问题,例如 this one about array sorting 似乎暗示 -Ofast 是答案(如果您准备接受它带来的变化)。然而,即使编译 -Ofast,性能与其他语言相比也很差。我正在使用 Swift 1.0 版(swift-600.0.34.4.8)。
以下是说明问题的简化示例:
import Foundation
class Holder {
var dictionary = Dictionary<Int, Int>()
func store(#key: Int, value: Int) {
dictionary[key] = value
}
}
let holder = Holder()
let items = 5000
for (var i: Int = 0; i < 5000; i++) {
holder.store(key: i, value: i)
}
用-O3编译运行需要两秒多:
xcrun swift -sdk $(xcrun --show-sdk-path --sdk macosx) -O3 Test.swift && time ./Test
real 0m2.295s
user 0m2.176s
sys 0m0.117s
使用 -Ofast 编译产生 3-4 倍的改进:
xcrun swift -sdk $(xcrun --show-sdk-path --sdk macosx) -Ofast Test.swift && time ./Test
real 0m0.602s
user 0m0.484s
sys 0m0.117s
相比之下,这个Java实现:
import java.util.Map;
import java.util.HashMap;
public class Test {
public static void main(String[] args) {
Holder holder = new Holder();
int items = 5000;
for (int i = 0; i < items; i++) {
holder.store(i, i);
}
}
}
class Holder {
private final Map<Integer, Integer> map = new HashMap<Integer, Integer>();
public void store(Integer key, Integer value) {
map.put(key, value);
}
}
又快了 6 倍:
javac Test.java && time java Test
real 0m0.096s
user 0m0.088s
sys 0m0.021s
仅仅是复制 Dictionary 的成本,因为它已经变异并存储在 Holder 实例中,导致 Swift 表现如此糟糕?删除Holder 并直接访问Dictionary 将表明它是。
这段代码:
import Foundation
var dictionary = Dictionary<Int, Int>()
let items = 5000
for (var i: Int = 0; i < 5000; i++) {
dictionary[i] = i
}
明显更快:
$ xcrun swift -sdk $(xcrun --show-sdk-path --sdk macosx) -O3 NoHolder.swift && time ./NoHolder
real 0m0.011s
user 0m0.009s
sys 0m0.002s
$ xcrun swift -sdk $(xcrun --show-sdk-path --sdk macosx) -Ofast NoHolder.swift && time ./NoHolder
real 0m0.011s
user 0m0.007s
sys 0m0.003s
虽然它提供了一个(希望如此)有趣的数据点,但在我的情况下,直接访问 Dictionary 是不可能的。我还能做些什么来让当前形式的 Swift 性能更接近这一水平?
【问题讨论】:
-
根据您的用例,您可以使用 Int 数组而不是 dict。
-
无论你做什么......很有可能当 Swift 发布用于生产用途时,这个问题已经解决了。我建议使任何解决方案都易于可逆,并不时检查。为了回答你的问题,我怀疑不是类慢而是函数调用。如果编译器设法内联函数,那应该可以解决问题......
-
我的用例在沸腾过程中有些丢失。关键实际上不是一个 Int。当类变量可用时,它很容易成为一个变量,但如果没有它们,这将是一个相当复杂的变化。
标签: performance swift