The MiscKit

Speed Considerations and the MiscKit


Home
Hot News
About
Press Kit
FAQ
Documentation
Download
Resources
Services
Search
Credits
Links
Contact Us


Most recent update was on February 7, 1996. If you'd like to submit something to the FAQ or update something in the FAQ, feel free to contact Don Yacktman or use our handy FAQ submission form.

Speed Considerations and the MiscKit

Can using the MiscString slow an app down? The quick and obvious answer is yes, but there are many reasons for that. The MiscString is designed to be utterly safe at the expense of efficiency and speed. What this means is that there are a lot of checks in the code that are in place to make sure that you don't do something stupid such as pass in NULL pointers, etc. The MiscString attempts to be completely crash proof, and about 95-99% of the time succeeds at it--but the cost is a pretty big performance hit if you use it a lot.

The novice's reaction would be to ask if removing the convenience methods from the MiscString would have much effect on the end performance of an application. It actually doesn't matter. You could have a billion methods and they won't really affect the performance very much. It is roughly the same as having a billion C functions linked into your app. They take up space, but don't affect the speed of the other functions. The exception to this is when you are calling convenience methods, which often just add default parameters and then call a "core" method. Speedups can be obtained by calling the core method, filling in the extra parameters with default values that you like. Here's a few random thoughts that aim towards being a general scheme for developing faster apps:

  1. Develop your app using the stock string. When you are sure that everything is working right, then split the MiscString stuff out of the MiscKit library and copy the source files to your project. You're going to start customizing the code.
  2. Next set yourself up for profiling, so that you know how often each method is called and how much time is spent in each method. For me,
  3. Now, go to the MiscString source and fine tune each method, starting with the ones that are eating up the most time (and typically those will be the ones that were called most often). Fine tuning involves several things:
    1. Convenience methods can hurt because the methods with fewer parameters just turn around and call other methods. You can get a speed up by making sure you call the core method. However, there is another alternative you might want to consider:
    2. Many methods will take speed hits because they have so many parameters. If you cut out some of the parameters, you can trim down the code, taking out various checks, etc., that can slow them down. If this is the case, you might do better to take the "core" implementation and copy it to the convenience method, and then take out the extras. This wasn't done in the original MiscString so that we'd have less code to maintain. (If there are, say, four convenience methods, we'd have four versions of the code to maintain and that could lead to all kinds of weird bugs and inconsistencies. We chose to take a speed hit to avoid this.) So, creating custom implementations can help you here.
    3. Another spot to tune is all the sanity checks. If you're sure your code works OK, take them out! You'll save a lot of cycles. The trouble is that if you wantonly throw pointers and numbers around without being sure that they are sane values, you could crash your app. Ideally your app is bug free at this point, so the checks are unnecessary. If you rely upon the MiscString to do all the sanity checking for you, then it would be wise to leave in the checks. If you code "safely", carefully watching all pointers, etc., then removing the checks should change nothing.
    4. Repeat this tuning process, reprofiling often so that you can find the "hot spots" where the time is spent and tune them first. I find that I usually spend about four hours doing this fine tuning from start to finish. I usually get at least a 30% speed improvement from it, often more.

I do this for every project where speed is critical, and repeat it each time because I end up tuning things in different ways to accomodate my app. This is a nasty, non-OOP approach to take, but when speed is critical you have to break the rules to really get it running fast. The tradeoffs are that you have to know what you are doing and be incredibly careful. I don't like to advocate breaking rules because it is bad practice, but I feel there are times when exceptions are warranted and can be justified.

I feel this approach breaks rules of pure OOP because you are opening up the "black box" that is the MiscString and fiddling with it, which in an ideal situations shouldn't be done and shouldn't be necessary. In this case I justify it by saying that I am altering the code to create a new object that is following different design goals: speed and efficiency over safety and convenience.

So ultimately, the question is - is MiscString too fat? In my opinion the interface is too bulky, but other than that it does fulfill its design goals. Other string classes--with other goals--will be quite different and you may decide that they are better for your project. Most people like the bulletproofing and the functionality of MiscString and are willing to sacrifice some performance to get it.

Someday we'd like to better tune the MiscString for speed, but that has not really been feasible to date. We haven't purposely written slow methods. The things that make them slow are all the safety checks that are in place and the flexibility of the methods. The checks are obviously a slow down because they take time. The flexibility isn't quite as obvious. Basically, we have to use parameters and other checks to control loops and other flow structures in the code, rather than hard coding certain behaviors. This increases the flexibility of the methods while slowing them down by adding code. Since the MiscString's design calls for safety and flexibility over speed, this is perfectly reasonable. We have optimized the methods for speed as much as is possible given the design goals.

With the move to OPENSTEP, I think I'll be able to do several things that will help to speed up the MiscString. That is the plan, at any rate. Because of the Foundation Kit's memory allocation schemes, we should be able to boost performance in several ways, since a lot of the performance hit comes from bringing MiscString objects into and out of scope so often. The FK can help alleviate a bit of that, especially for operations that copy constant strings.

Now, moving on to the rest of the kit, what can we do to improve performance? Remembering that 90% of the speedups take 10% of the effort, I personally believe that you'll hit that break-even point before you finish optimizing the MiscString, especially for any app that does a lot of string manipulation. Much of the MiscKit relies heavily upon the MiscString, so speeding up string operations will actually affect the rest of the kit quite a bit. (The MiscMergeKit will show a marked improvement, for example!)

If you follow NeXT's hints for speedup in /NextLibrary/Documentation/NextDev/Concepts/Performance you'll end up with a pretty well optimized application. Most of the MiscKit is already quite well optimized for speed, so there really isn't much more that you can do. If, however, you do find ways to obtain major improvements, do be sure to send them in as submissions so that other MiscKit users may benefit!



- Don Yacktman



If you have other ideas or comments about this page, please feel free to send them to Don Yacktman via email to don@misckit.com.



Questions? Contact our webmaster via email to don@misckit.com. .