macos-为什么在此图像处理测试中,Swift比C慢100倍?

这个问题在这里已有答案:

  • Swift Beta性能:对数组进行排序                                     9个答案

像许多其他开发人员一样,我对Apple的新Swift语言感到非常兴奋。 苹果声称它的速度比Objective C快,可用于编写操作系统。 从我到目前为止所学到的,它是一种静态类型语言,能够精确控制确切的数据类型(例如整数长度)。 因此,看起来确实具有良好的潜在处理性能关键任务,例如图像处理,对吗?

这就是我进行快速测试之前的想法。 结果真的让我感到惊讶。

这是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。 换句话说,处理一帧需要1毫秒的C代码:

$ 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)
}

构建命令行为:

xcrun swift -O3 test.swift -o test

在此,我使用相同的260337986143151818208级别优化标记来使比较有希望。 但是,结果速度要慢100倍:

$ time ./test

real    0m1.172s
user    0m1.146s
sys     0m0.006s

换句话说,处理一帧需要花费Swift约120毫秒,而C仅花费1毫秒。

发生了什么?

更新:我正在使用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

更新:通过不同的运行迭代获得更多结果:

这是不同数量的“帧”的结果,即将主-Ofast循环编号从10更改为其他编号。 现在注意,我得到的C代码时间更快(高速缓存高速缓存?),而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

更新:`-Ofast`帮助

@mweathers建议使用-Ofast,使Swift速度达到合理范围。

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

Penghe Geng asked 2019-11-07T07:22:46Z
2个解决方案
24 votes

建筑:

xcrun swift -Ofast test.swift -o test

我正在以下时间:

real    0m0.052s
user    0m0.009s
sys 0m0.005s
mweathers answered 2019-11-07T07:23:16Z
11 votes

让我们仅关注问题的答案,该问题的开头是“为什么”:因为您没有打开优化,而Swift严重依赖于编译器优化。

也就是说,在C中进行图像处理确实是愚蠢的。 那就是CGImage和朋友的目的。

gnasher729 answered 2019-11-07T07:23:47Z
translate from https://stackoverflow.com:/questions/24102609/why-swift-is-100-times-slower-than-c-in-this-image-processing-test