Path: utzoo!attcan!uunet!swlabs!gaboon!kermit!andyk From: andyk@kermit.UUCP (Andy Klapper) Newsgroups: comp.lang.objective-c Subject: Re: Real-time coding practices in Objective C Keywords: objective-c Message-ID: <5741@kermit.UUCP> Date: 30 Oct 90 14:52:41 GMT References: <129@contel0> Reply-To: andyk@kermit.UUCP (Andy Klapper) Organization: The Stepstone Corporation, Sandy Hook, CT 06482 Lines: 147 In article <129@contel0> barton@contel0.UUCP (Matthew Barton - R+D Software eng) writes: >Goal: Time critical code should perform as well as C code, while retaining the >advantages of object-oriented design. > >Coding guidelines: > >2. Don't use inherited methods. They cannot be statically bound. >Inherited data is ok. NOT TRUE !! Inherited methods can be statically bound just like methods defined in the class that calls it ! The following code fragment when compiled will show this. file -> One.h #import "Object.h" @interface One : Object {} - aOneMethod; @end file -> Two.h #import "One.h" @interface Two : One {} - testMethod; @end file -> Two.m #import "Two.h" @implementation Two - testMethod { [(Two *) self aOneMethod]; // Note: self must be cast to a type for // static binding to work. This is VERY // dangerous as a sub class that over rides // the aOneMethod would not work as expected. } @end >3. Don't nest method invocations, since the intermediate results are of >type "id". Explicitly declare the intermediate variables. > Example: replace this: > [vo_class2 m_status:[vo_class1 m_status]]; > > with > > some_value = [vo_class1 m_status]; > [vo_class2 m_status:some_value]; > Also NOT TRUE !!! as long as the type of vo_class1 is known, and the sBind switch is set this will work. Add the following lines to the above example to show that this will work as well. file -> One.h add the method prototype - createOne; file -> Two.m add to testMethod the line [[(Two *) self createOne] aOneMethod]; NOTE: Both of these examples were run on a Sun 3 under Sun OS 4.0.3 with the current released version of Objective-C. If anybody would like the full examples I can Email them to you. >4. Avoid Stepstone library objects such as String, Collection, etc, >since these do not follow the guidelines given above. >Code your own objects, and re-use them. > The ICpak101 libraries were designed to be generalized reusable components. When you get to the optimization phase you should optimize the methods that will help you the most to optimize. For example Stepstone created a new Set class (HashSet) as part of ICpak201 because the performance of a general purpose Set class was not good enough. > >This kind of coding raises all kinds of questions: > Could Stepstone provide an alternate version of runtime and ICpak101 > libraries, which was optimized for speed? We could, but then we should offer several different versions of each class. Each version would have to be optimized for a different set of conditions. For example Stepstone should then provide different optimized versions of osort (one optimized for the case of random data, one optimized for data that is already mostly sorted ...). The point being that algorithmic changes get you more bang for the buck, but tend to be VERY application specific. > > Could static binding be improved to recognize the type of the receiver > just from a cast, rather than the data declaration? This is already the case. In a future release the compiler will also allow for static binding to class objects and to super inside of class methods. > Can the > inherited methods be static bound, in code where static (compile-time) > analysis shows that there is no method over-ride done by > the sub-classes? Given the way that static binding is implemented in Objective-C, where the method is defined is of no concern. > > Does anyone have any other suggestions for speed improvement, > which are specific to the Objective-C language (as opposed to > just general-purpose good-programming practices)? I am currently working on a new section/appendix for the Objective-C manual that deals with optimizing Objective-C code for speed. (I may be able to send you a working copy if you want (I'd have to check first)). Here are a couple things that I think you missed. 1) The 'methodFor:' method provides a way of getting an implementation (function) pointer for an object, selector pair at runtime. The 'methodFor:' method allows for a little more flexibility in your code. For example this mechanism allows you to define a uniform collection that is optimized with the knowledge that all of it's elements are of the same time. Static binding will only allow you to define a collection that contains all objects of a specific type because the type of the receiver has to be determined at compile time. 2) You have not mentioned anything about memory allocation and freeing. Alot of time can be spent allocating and freeing objects in an Objective-C program. You may want to cache some objects for reuse or use objects allocated off of the stack. When allocating objects off of the stack there are a couple of things that you ought to know. One, the data in an object allocated off of the stack is NOT initialized. The user is responsible for initializing the data themselves (- initialize is the most common way). Two, the current release of the compiler does not properly set an attribute bit that prevents the free method from trying to call 'free()' to free the memory used by the object. (The next release will) What this means is that if the initialization routine creates any additional objects you will have to create a new free method that will release them, but not self. > >On un-related issues: I will pass you suggestions on. > > matt -- The Stepstone Corporation Andy Klapper 75 Glen Rd. andyk@stepstone.com Sandy Hook, CT 06482 uunet!stpstn!andyk (203) 426-1875 fax (203)270-0106