Path: utzoo!censor!geac!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!julius.cs.uiuc.edu!apple!agate!shelby!msi.umn.edu!noc.MR.NET!gacvx2.gac.edu!gacvx2.gac.edu!scott From: scott@mcs-server.gac.edu (Scott Hess) Newsgroups: comp.sys.next Subject: Re: speed of access methods vs. object_getInstanceVar Message-ID: Date: 8 Jan 91 02:31:56 GMT References: <4755@media-lab.MEDIA.MIT.EDU> Organization: Gustavus Adolphus College Lines: 58 Nntp-Posting-Host: mcs-server.gac.edu In-reply-to: simsong@daily-bugle.media.mit.edu's message of 7 Jan 91 21:47:16 GMTLines: 58 In article <4755@media-lab.MEDIA.MIT.EDU> simsong@daily-bugle.media.mit.edu (Simson L. Garfinkel) writes: I was interested as to whether it is faster to access the instance variables of an object via accessor methods or via the object_getInstanceVariable() function, so I did a test. I just did some quick testing to verify a point. In the case of object_getInstanceVariable(), the function follows the isa instance variable to find the class of the object. Then, it searches that data structure to find the offset of the variable. Meanwhile, the method version can access the variable directly (as if it were a structure, which is how the method will see it), with the overhead being in the lookup of the method. Since methods are compiled into SELs for identification, and each class keeps a lookup table of frequently called methods, this is fairly fast. In the simple case given by Simson, this is all that happens. Either method of access is fairly close. The advantage of the accessor method really shows, though, when subclasses are used. I took the sample code, and subclassed MyObject with MyNewObject, and then subclassed MyNewObject with MyNewNewObect. Both subclasses did not have any new variables or methods. The times for both routines stayed approxiametely constant. But, when I added 3 new instance variables of type int to each of the subclasses, the time for the object_getInstanceVariable() version shot up almost 3x! The time using the accessor method stayed about the same. The reason is that, in this case, object_getInstanceVariable() must first search through the first isa pointer, but cannot find the variable there. Then, it must go to the superclass, search its variable list, and not find it there, either. Lastly, it gets to MyObject, and finds the variable there, and returns it. Meanwhile, the first call to getX will cause the IMP for getX's SEL to be placed in MyNewNewObject's cache, and from then on it will be quickly found. The moral of the story? Use accessor methods. In most cases, they are not that slow if they are used enough - if they aren't used enough to stay in the cache, you probably shouldn't be worrying that much about a couple cycles, because it won't add up. One last thing. In some cases, you can use +(IMP)instanceMethodFor:(SEL)aSel; to get a function which can be used instead of a method call. This should only be used inside loops, or other fairly safe places where the object isn't going to change class. It would not be too good to use an IMP gotten for Responder on a Button . . . anyhow, I just did a test. I added a call to get the IMP for getX to Simson's code, and a argument -i to check for when this should be called. The result? Execution time was cut to approxiamately 35% of what is was for the ti -m case. This is, of course, due to removal of the cache search from the cycle. Hopefully, this helps someone out there. One never knows :-). Well, it helps me, so I figured I'd post this to the net at large. Later . . . -- scott hess scott@gac.edu Independent NeXT Developer GAC Undergrad "Tried anarchy, once. Found it had too many constraints . . ." "Buy `Sweat 'n wit '2 Live Crew'`, a new weight loss program by Richard Simmons . . ."