当我以 Apple 风格的方式将字符串传递给函数并对其进行十亿次测试时,大约需要 42,001 秒:
- (void)test:(NSString *)str {
NSString *test = str;
if (test) {
return;
}
}
NSString *value = @"Value 1";
NSLog(@"START");
for (int i = 0; i < 1e9; i++) {
[self test:value];
}
NSLog(@"END");
但是然后将指针作为值传递(假设我的 test
函数将是只读样式),如下所示:
- (void)test:(NSString **)str {
NSString *test = *str;
if (test) {
return;
}
}
NSLog(@"START");
for (int i = 0; i < 1e9; i++) {
[self test:&value];
}
NSLog(@"END");
..只需要 ~26,804
秒。
为什么苹果将第一个示例作为常规做法进行推广,而后者的表现却似乎如此不同?
我了解到 Foundation 应用的免费桥接
,但如果差异相对较大,那么附加值是什么?只需升级一些像这样的主要函数参数,整个应用程序的运行速度就会提高 100% 以上,那么这不是 Apple 在指导如何使用 Objective-C 构建应用程序的方式上的一个相当大的缺陷吗?/p>
最佳答案
您不会使用 NSString **
语法,因为这表明您调用的方法可以更改 value
指向的内容。除非这确实是正在发生的事情,否则你永远不会这样做。
简单的 NSString *
示例可能需要更长的时间,因为在没有任何优化的情况下,NSString *
再现可能会添加/删除对 的强引用>value
当方法被调用并返回时。
如果您打开优化,行为会发生变化。例如,当我使用 -Os
“最快,最小”build设置时,NSString *
再现实际上比 NSString **
再现更快。即使性能更差,我也不会仅仅因为每次调用快了 0.0000152 秒就编写了让我遇到各种问题的代码。我会找到其他方法来优化代码。
引用唐纳德·高德纳 (Donald Knuth) 的话:
Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. [Emphasis added]
目标始终是编写功能意图明确、类型处理最安全的代码,然后在可能的情况下使用编译器自身的内部优化功能来解决性能问题。仅在绝对必要时牺牲代码可读性以及维护和调试的简易性。
关于objective-c - 为什么 Cocoa 开发中没有动机传递指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37057109/