Performance of object_setClass() instead of assigning isa pointer

只愿长相守 提交于 2019-12-10 11:18:28

问题


I noticed with with the latest update to XCode (4.6), I was given a warning about a couple of lines in JSONKit.m. Specifically, lines that set the class of an object:

dictionary->isa = _JKDictionaryClass;

These are marked as deprecated with a note that the preferred method was to use object_setClass():

object_setClass(dictionary, _JKDictionaryClass);

When I asked why it was preferred to simply silence the warning, the response was:

Everything works fine even if new Xcode version complains, I don't want to :
1) test each project where i use JSONKit to check if everything goes fine after object_setClass()
2) loose cpu cycles, which is the reason why i use JSONKit over NSJSONSerialization for example. My current application parses json files that weights 600K-1M

Just how much of a performance hit are we talking about here?

NOTE:

I am more interested in

dictionary->isa = _JKDictionaryClass vs object_setClass()

than JSONKit vs NSJSONSerialization.


回答1:


The reasoning is that function calls always have some overhead: the arguments should be pushed onto the stack (and caller-saved registers too), then the instruction pointer should be updated, then all this should be done in reverse when the function returns. It's generally more computationally expensive than simply dereferencing a pointer (which can be as simple as mov [dest] [src].




回答2:


The reasoning has nothing to do with a performance hit, and never did. The definition of an object as having an isa pointer is an implementation detail, and has been as much since at least Objective-C 2.0 (and conceptually has been for much longer). The Clang compiler folks and Apple, especially the people involved in optimizing the runtime, would like nothing better than to be able to define an object as having whatever internal structure is fastest instead of always maintaining this isa field. The fact that isa exists, the fact that it exists at the start of every object, and that the isa is simply a Class pointer, has always theoretically been subject to change. It hasn't changed up to this point more because of the compatibility break doing so would cause than anything else.

Also, the performance characteristics of object_setClass versus object->isa = blah are a bit of a joke. The CPU is liable to, at the hardware level, optimize out the overhead of the function call long before it ever affects your code. If you're worrying about the number of cycles involved in pushq %rbp; movq %rsp, %rbp; movq %rsi, (%rdi); popq %rbp; ret, you're not in the Objective-C problem domain anymore - you should be working at the C or assembly language levels already if your code is sensitive to a different made by five instructions.

And even all of that aside, there are few good reasons to be setting the class of an object in this fashion to begin with. Why in the world are you doing this, and how is it helpful to you?

Finally, I might add that the Clang team has better things to do than add warnings purely for the sake of dealing with this kind of "performance" "issue". Almost all warnings (not all, but most) mean that you're doing something wrong, even if it happens to work at the moment in the cases you're testing. This code would already break for any object that uses tagged pointers. This is what Xcode is trying to tell you.

Edit: It's been pointed out to me that the question wasn't about the reason for the warning itself, but rather the particular performance characteristics of the function in question. As I mentioned in my answer, the performance hit is so small that if it were relevant to your code, you shouldn't be using Objective-C in the first place. My apologies for misunderstanding the original question.



来源:https://stackoverflow.com/questions/14986248/performance-of-object-setclass-instead-of-assigning-isa-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!