Question

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.

Was it helpful?

Solution 2

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].

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top