为什么Swift在这个image processingtesting中比C慢100倍?

和许多其他开发者一样,我对于苹果的新Swift语言感到非常兴奋。 苹果宣称其速度比Objective C更快,可用于编写操作系统。 从我迄今为止所了解到的情况来看,这是一种静态types语言,能够精确控制确切的数据types(如整数长度)。 所以它看起来像具有良好的潜在处理性能的关键任务,如image processing,对吗?

这是我进行快速testing之前的想法。 结果真的让我很吃惊。

这里是一个简单的C代码片段:

test.c的:

#include <stdio.h> #include <stdint.h> #include <string.h> uint8_t pixels[640*480]; uint8_t alpha[640*480]; uint8_t blended[640*480]; void blend(uint8_t* px, uint8_t* al, uint8_t* result, int size) { for(int i=0; i<size; i++) { result[i] = (uint8_t)(((uint16_t)px[i]) *al[i] /255); } } int main(void) { memset(pixels, 128, 640*480); memset(alpha, 128, 640*480); memset(blended, 255, 640*480); // Test 10 frames for(int i=0; i<10; i++) { blend(pixels, alpha, blended, 640*480); } return 0; } 

我使用以下命令将其编译在我的Macbook Air 2011上:

 clang -O3 test.c -o test 

10帧处理时间约为0.01s。 换句话说,它需要C代码1ms来处理一个帧:

 $ time ./test real 0m0.010s user 0m0.006s sys 0m0.003s 

然后我有一个相同的代码的Swift版本:

test.swift:

 let pixels = UInt8[](count: 640*480, repeatedValue: 128) let alpha = UInt8[](count: 640*480, repeatedValue: 128) let blended = UInt8[](count: 640*480, repeatedValue: 255) func blend(px: UInt8[], al: UInt8[], result: UInt8[], size: Int) { for(var i=0; i<size; i++) { var b = (UInt16)(px[i]) * (UInt16)(al[i]) result[i] = (UInt8)(b/255) } } for i in 0..10 { blend(pixels, alpha, blended, 640*480) } 

构build命令行是:

 xcrun swift -O3 test.swift -o test 

在这里,我使用相同的O3水平优化标志来使比较有希望公平。 但是,由此产生的速度是100倍慢:

 $ time ./test real 0m1.172s user 0m1.146s sys 0m0.006s 

换句话说,需要Swift〜120ms来处理一个只需要1ms的C帧。

发生了什么?

更新:我正在使用叮当声:

 $ gcc -v Configured with: --prefix=/Applications/Xcode6-Beta.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 6.0 (clang-600.0.34.4) (based on LLVM 3.5svn) Target: x86_64-apple-darwin13.2.0 Thread model: posix 

更新:不同运行迭代的更多结果:

这里是不同数量的“帧”的结果,即将主循环数从10更改为其他数字。 注意现在我得到更快的C代码时间(caching热点?),而Swift时间不会变化太多:

  C Time (s) Swift Time (s) 1 frame: 0.005 0.130 10 frames(*): 0.006 1.196 20 frames: 0.008 2.397 100 frames: 0.024 11.668 

更新:` – 快速`帮助

随着-Ofastbuild议的-Ofast,Swift的速度达到了合理的范围。

在我的笔记本电脑上,带有-Ofast的Swift版本获得10帧0.013s和100帧0.048s,接近C性能的一半。

搭build:

xcrun swift -Ofast test.swift -o test

我得到的时间:

 real 0m0.052s user 0m0.009s sys 0m0.005s 

让我们把注意力集中在以“为什么”开始的问题的答案上:因为您没有优化,Swift严重依赖于编译器优化。

这就是说,在C中进行image processing确实很愚蠢。 这就是你有CGImage和朋友的。