Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 优化NSNumber numberWithInt:_Iphone_Objective C_Performance_Nsnumber - Fatal编程技术网

Iphone 优化NSNumber numberWithInt:

Iphone 优化NSNumber numberWithInt:,iphone,objective-c,performance,nsnumber,Iphone,Objective C,Performance,Nsnumber,我正在分析一个iPhone应用程序,我注意到一个奇怪的模式。在某个频繁调用的代码块中 [item setQuadrant:[NSNumber numberWithInt:a]]; [item setIndex:[NSNumber numberWithInt:b]]; [item setTimestamp:[NSNumber numberWithInt:c]]; [item setState:[NSNumber numberWithInt:d]]; [ite

我正在分析一个iPhone应用程序,我注意到一个奇怪的模式。在某个频繁调用的代码块中

    [item setQuadrant:[NSNumber numberWithInt:a]];
    [item setIndex:[NSNumber numberWithInt:b]];
    [item setTimestamp:[NSNumber numberWithInt:c]];
    [item setState:[NSNumber numberWithInt:d]];
    [item setCompletionPercentage:[NSNumber numberWithInt:e]];
    [item setId_:[NSNumber numberWithInt:f]];
…对[NSNumber numberWithInt:]的第一次调用花费的时间太长,大约是其余调用的10-15倍。我已经验证了如果我洗牌这些行,结果是一致的(第一行总是慢行,比例相同)。有什么事我不知道吗


可能这是因为这个块在try/catch中?

如果我不得不猜测的话,NSNumber在它的
+load
实现中执行一些代码,这会减慢对类的初始调用。还要注意的是,
NSNumber
缓存了它的返回值,因此将来使用相同的值调用
+numberwhithint:
会比以前更快,这可能是问题的一部分。

可能第一个值要大得多?除了CoreFoundation的CFNumber缓存之外,“新”运行时还使用标记指针,允许将24位范围内的整数直接编码到指针中,然后运行时通过查看最后一位来确定它是标记指针(通过查看最后一位之前的3位和目标数字大小(8、16、32、64位,使用之前的下4位),这是一个CFNumber)。
在32位系统(当前的iPhone)上,这意味着对于(“小”)负32位数字或大的正数,CoreFoundation将分配一个对象。对于其他所有内容,它使用以下更快的表达式:

    case kCFNumberSInt32Type: {
            int32_t value = *(int32_t *)valuePtr; // this loads the actual numerical value passed to CFNumberCreate()
#if !__LP64__
            // We don't bother allowing the min 24-bit integer -2^23 to also be fast-pathed;
            // tell anybody that complains about that to go ... hang.
            int32_t limit = (1L << 23);
            if (value <= -limit || limit <= value) break;
#endif
            uintptr_t ptr_val = ((uintptr_t)((intptr_t)value << 8) | (2 << 6) | kCFTaggedObjectID_Integer);
            return (CFNumberRef)ptr_val;
        }
案例kCFNumberSInt32Type:{
int32_t value=*(int32_t*)valuePtr;//这将加载传递给CFNumberCreate()的实际数值
#如果__
//我们不需要费心让最小24位整数-2^23也可以快速路径;
//告诉任何抱怨这件事的人去…等等。

int32\u t限制=(1L)每次运行的第一次调用占用的时间更长,还是启动应用程序后的第一次调用?第一次调用一个类的方法将花费更长的时间,因为运行时必须搜索实现,但它会为将来缓存它。您可能还需要考虑只使用int而不是NStEnter。
保留代表低值整数的实例的某种缓存;设置该缓存很可能就是它正在做的事情,但我认为你的意思是
+初始化
,而不是
+加载
。这是在类收到第一条消息之前发送的。谢谢,根据其他文档,这似乎是正确的答案在线。虽然官方API中没有记录,但低值确实被缓存。一些人报告低整数值的重新计数高于预期值,这与此时间问题一致。我刚刚发布了另一个答案。考虑到NSNumber实际上是CFNumber的包装器,它受到CFNumber优化和limi的影响tations——它是在@Riviera的代码作为运行时设置的一部分运行之前很久设置的,或者在
UIApplicationMain()
期间设置的,因此
+load
极不可能是性能差异的原因,考虑到@Riviera说这个块被称为“频繁”,这意味着它总是比较慢,而不仅仅是第一次(instruments计算平均值)。在提问时,情况并非如此。iOS 6和Mac OSX Lion中添加了带标记的整数,因此在给定的情况下,这不是一个问题。我们不应该将此作为个人讨论。我只想将其添加到“旧”中问题-根据我的信息,在iOS5中,带标签的指针被添加到运行时中,同时支持弱引用。