Why Swift is 100 times slower than C in this image processing test?
本问题已经有最佳答案,请猛点这里访问。
像许多其他开发者一样,我对苹果的新的Swift语言感到非常兴奋。苹果声称它的速度比目标C快,可以用来编写操作系统。据我目前所学,它是一种静态类型的语言,能够精确地控制精确的数据类型(比如整数长度)。所以,它看起来确实有很好的潜在处理性能关键任务,比如图像处理,对吧?
这就是我在做快速测试之前的想法。结果真让我吃惊。
下面是C中的一个简单代码段:
测试:C:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #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上编译了它:
1 | clang -O3 test.c -o test |
10帧处理时间约为0.01s,换言之,C码1 ms处理一帧:
1 2 3 4 |
然后我有一个快速版本的相同代码:
斯威夫特:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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) } |
生成命令行是:
1 | xcrun swift -O3 test.swift -o test |
在这里,我使用相同的
1 2 3 4 5 |
换言之,处理一帧需要大约120ms的时间,而处理一帧只需要1 ms的时间。
怎么搞的?
更新:我正在使用clang:1 2 3 4 5 | $ 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 |
更新:不同运行迭代的更多结果:
这里是不同数量"帧"的结果,即将主
1 2 3 4 5 | 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 |
更新:`-ofast`帮助
有了@mweathers建议的
在我的笔记本电脑上,带
建筑与:
我得到的时间是:
1 2 3 | real 0m0.052s user 0m0.009s sys 0m0.005s |
让我们集中讨论这个问题的答案,它从一个"为什么"开始:因为您没有启用优化,而Swift严重依赖于编译器优化。
也就是说,在C中进行图像处理是非常愚蠢的。这就是你拥有CGIMAGE和朋友的目的。