我已经使用对象-c类的默认设置器来允许某种类型的KVO,而实际上并没有向属性添加一个观察者。这个很好用。但在某些情况下,我需要在这个系统周围分配数十万个属性。
因此,出于性能原因,我有一个自定义属性描述符,允许直接设置ivar。为了优化性能,我保存了一些有关属性的信息。
剩下的一个位置,我对更改相当小心,是使用object_setIvar(),它占60%的CPU时间分配期间,根据仪器。罪魁祸首是object_setIvar正在调用_class_getVariable,这比实际赋值(objc_storeStrong())花费的时间长3倍。
长话短说:既然我可以预先将所有信息缓存到类的属性中,作为我的属性描述符的一部分,我如何更快地设置ivar (避免object_setIvar())?
下面是我的属性描述符类的实际对象设置器函数(还有一个设置数值的等效函数):
- (id)setObjectValueNoKVOForOwner:(id)instance newObject:(id)newObject
{
Class cls = object_getClass(instance);
BOOL retainNewValue, copyNewValue, releaseOldValue;
switch (self.setterSemantics)
{
case MemberDescriptionSetterSemanticsAssign:
retainNewValue = NO;
copyNewValue = NO;
releaseOldValue = NO;
break;
case MemberDescriptionSetterSemanticsRetain:
retainNewValue = YES;
copyNewValue = NO;
releaseOldValue = YES;
break;
case MemberDescriptionSetterSemanticsCopy:
retainNewValue = NO;
copyNewValue = YES;
releaseOldValue = YES;
break;
}
if (!_ivar)
{
_ivar = class_getInstanceVariable(cls, self.attributes.ivarName);
}
if (_ivar)
{
id oldObject = object_getIvar(instance, _ivar);
if (newObject != oldObject)
{
if (retainNewValue)
{
newObject = [newObject retain];
}
else if (copyNewValue)
{
newObject = [newObject copy];
}
object_setIvar(instance, _ivar, newObject); // Improve this: avoid _class_getVariable
if (releaseOldValue)
{
[oldObject release];
}
}
}
return [newObject autorelease];
}更新:
我找到了与object_setIvar()相关的源代码:https://github.com/opensource-apple/objc4/blob/master/runtime/objc-class.mm http://www.opensource.apple.com/source/objc4/objc4-532.2/runtime/objc-private.h http://www.opensource.apple.com/source/objc4/objc4-532.2/runtime/objc-runtime-new.mm
实现自己版本的object_setIvar()似乎并不“邪恶”,只是将已知的类作为参数添加到其中。不幸的是,它需要一个私有的头文件。当我瞄准iOS的时候,现在看来我应该放弃希望了。
更新2:
我在苹果的消息来源中发现这个评论是在浪费时间的地方:
"// FIXME:这可以优化。“
因此,我可能会在这一点上放弃,希望将来会有所改善。实际上,我真的不明白在一些基本的东西中存在这样一个瓶颈,比如为一个属性设置一个值。另一方面,很高兴看到苹果的程序员也只是人:)。
发布于 2013-11-01 13:20:22
这个系统周围有数十万个属性
虽然我不是这个主题的专家,但我对处理器-内存总线内部工作方式的理解表明,最好改变附近的值 (L1-3缓存命中),而不是彼此相距很远的值(L1-3缓存丢失)。
因此,对于快速存储的值,使用简单的连续C数组不是更好吗?
https://stackoverflow.com/questions/19725352
复制相似问题