【问题标题】:Why is this C-style code 10X slower than this obj-C style code?为什么这个 C 风格的代码比这个 obj-C 风格的代码慢 10 倍?
【发布时间】:2009-09-09 18:46:08
【问题描述】:

//obj C 版本,有一些 - 18,000 次迭代不到一秒

for (NSString* coordStr in splitPoints) {

  char *buf = [coordStr UTF8String];
  sscanf(buf, "%f,%f,", &routePoints[i].latitude, &routePoints[i].longitude);

  i++;

}

//C 版本 - 18,000 次迭代超过 13 秒

for (i = 0; buf != NULL; buf = strchr(buf,'['), ++i) {

  buf += sizeof(char);
  sscanf(buf, "%f,%f,", &routePoints[i].latitude, &routePoints[i].longitude);

}

作为一个必然的问题,有没有办法让这个循环更快?

另请参阅此问题:Another Speed Boost Possible?

【问题讨论】:

  • 你为什么不转储反汇编并查看原始差异?还是使用分析器?
  • 你知道sizeof(char) == 1 适用于所有平台,对吧?
  • obj C 版本中的splitPoints 是什么?我的意思是,C 版本正在拆分 buf ......而且,显然,当达到 sn-p 时,obj C 版本已经做到了。

标签: iphone c objective-c cocoa-touch


【解决方案1】:

测量,测量,测量。

使用 Instruments 中的 Sampler 工具测量代码。

话虽如此,与 Objective-C 代码相比,C 代码的效率明显低下。

也就是说,快速枚举——for(x in y) 语法——非常快,更重要的是,它暗示splitPoints 是一个数组或集合,其中包含一组已经被解析为单个对象的数据。

第二个循环中的strchr() 调用意味着您正在动态解析内容。就其本身而言,strchr() 是一个循环操作,并且会消耗时间,而且随着目标字符出现之间的字符数的增加而增加。

不过,这都是猜测。与所有优化一样,推测是无用的,使用提供的 [相当棒的] 工具集收集具体数据是唯一确定的方法。

一旦你测量过,你就可以让它更快。

【讨论】:

  • 对于它的价值,我无法想象strchr() 效率极低。这是一个简单的功能,应该进行相当好的优化。也就是说,它仍然可能很糟糕。
  • strchr() 很快。不同之处在于数组意味着解析已经完成,并且带有strchr 的循环增加了在循环中进行解析的成本。
【解决方案2】:

与性能无关,您的 C 代码中有错误。 buf += sizeof(char) 应该只是 buf++。指针运算总是以类型大小为单位移动。在这种情况下它工作得很好,因为 sizeof(char) 是 1。

【讨论】:

  • 这与手头的问题无关。对于编译器来说,sizeof(1)、sizeof(char) 和 1 是完全一样的。因此,虽然是一个错误,但它不能成为性能差异的根源。
  • 哦,来吧。这是一个完全符合事实的评论,也是一个有用的风格注释;不必要地使用 sizeof 总是一个很好的线索,表明您正在阅读的代码中存在指针错误。而且您的更正实际上是不正确的。 sizeof(1) == sizeof(int) == 4 在大多数平台上
  • 事实上,是的,但它与手头的问题无关。 (是的,我在 sizeof(1) 中也犯了一个事实错误)。
【解决方案3】:

Obj C 代码看起来像是预先计算了一些分割点,而 C 代码在每次迭代中寻找它们。简单的答案?如果 N 是buf 的长度,M 是分割点的数量,那么看起来你的两个 sn-ps 的复杂性是 O(M) 与 O(N*M);哪个慢?

edit: 确实让我吃惊,有些人会认为 C 代码在公理上比任何其他解决方案都快。

【讨论】:

  • C 代码只是在循环的每次迭代中寻找下一个 '[',而不是查看每个分割点的整个 buf 长度,对吧?
  • 不,但最坏的情况是它必须遍历整个字符串。所以它直接取决于字符串的长度,而不是常数。
  • 呸,我的意思是“是的,但是”。需要咖啡。
【解决方案4】:

向量化可用于加速 C 代码。

例子:

Even faster UTF-8 character counting

(但也许只是尽量避免在循环条件下调用 strchr()。)

【讨论】:

    猜你喜欢
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 2013-02-15
    • 2017-11-04
    • 1970-01-01
    相关资源
    最近更新 更多