math expression evaluation - very fast - with objective-c - objective-c

i want to evaluate a math expression like y = 2(x * x) + 2.
But i need it in a loop, where the x changes maybe 100000 times.
I have written code to translate the expression in a parse tree.
Then i have a method to evaluate the parse tree.
- (double) evaluate:(TreeNode *)node variable:(double)x
{
if ([node _operand] != 0)
{
return [node _operand];
}
else if ([node _variable] != NULL)
{
return x;
}
else if ([node _operator] != NULL)
{
if ([[node _operator] isEqualToString: #"+"])
{
return ([self evaluate:[node left] variable:x] + [self evaluate:[node right] variable:x]);
}
else if ([[node _operator] isEqualToString: #"-"])
{
return ([self evaluate:[node left] variable:x] - [self evaluate:[node right] variable:x]);
}
else if ([[node _operator] isEqualToString: #"*"])
{
return ([self evaluate:[node left] variable:x] * [self evaluate:[node right] variable:x]);
}
else if ([[node _operator] isEqualToString: #"/"])
{
return ([self evaluate:[node left] variable:x] / [self evaluate:[node right] variable:x]);
}
}
return 0;
}
Someone said: if i gotta go for speed, i could translate the expression into C code, compile and link it into a dll on-the-fly and load it (takes about a second). That, plus memoized versions of the math functions, could give me the best performance.
How can i achive that ?
How can i compile the math expression into C code and compile and link it into a dll or so. And then load it on the fly to speed the loop up ?
Thanks a lot !
Chris

My advice: Do not write this code yourself. Having written code that does this, there are some things to be aware of:
Parsing mathematical expressions is not a trivial problem, if you're going to do it correctly and fully. You have to consider things like the associativity of each operator: what happens if you find more than one of the same operator in an expression? Which one do you evaluate first? How do you deal with operators whose precedence changes depending on their context? (for example, the negation operator) These are hard questions, and very few implementations get it right.
As was mentioned in a comment on the question, there are some things that can do this for you already:
NSPredicate. Pros: built-in, reasonably fast, decent precision. Cons: the exponent is parsed with incorrect associativity, not extensible, does not support implicit multiplication (i.e., 2(x*x)), does not parse the negation operator correctly.
GCMathParser. Pros: very fast, decent precision. Cons: not extensible, does not support implicit multiplication, does not parse the negation operator correctly.
DDMathParser. Pros: excellent precision, extensible, supports implicit multiplication. Cons: not quite as fast as the other two, due to the parsing engine and high precision math
Obviously, I recommend DDMathParser (I wrote it). In your case, you'd want to do something like this:
NSError *error = nil;
NSString *math = [DDExpression expressionFromString:#"2($x * $x) + 2" error:&error];
for (int x = 0; x < 100; ++x) {
NSNumber *variable = [NSNumber numberWithInt:x];
NSDictionary *sub = [NSDictionary dictionaryWithObject:variable forKey:#"x"];
NSNumber *value = [math evaluateWithSubstitutions:sub evaluator:nil error:&error];
NSLog(#"value: %#", value);
}
DDMathParser is available on GitHub: https://github.com/davedelong/DDMathParser . Please be mindful of its license (free for use with attribution).
However, if you're ok with sacrificing some precision (and a couple of cases of it being incorrect) in exchange for blazing fast speed, I'd recommend using GCMathParser.

If you were to performance analyze that code, you'd [very most likely almost 100% assuredly] find that string comparison is what is killing your performance.
An easy fix is to split parsing from evaluation. That is, parse the expression into an intermediate form (like what jills and Rudy allude to, but simpler) and then evaluate that intermediate form.
That is, you might create a "parse:" method that [recursively] walks your tree of nodes, parses each, and then sets a property to some # representing the operator.
typedef enum {
PlusOperator,
SinOperator,
..... etc ....
} OperatorID;
#property(nonatomic) OperatorID operatorID;
Then, your evaluate:variable:'s if/else would be replaced with a switch statement.
switch([node operatorID) {
case PlusOperator:
....
break;
... etc ...
Hi, thanks a lot. But i already parsed the expression and have build a
tree, which i evaluate with the method above. What i need is a faster
evaluation in a loop.
Don't represent the parse tree as strings.
I.e. instead of _operator returning an NSString, make it return an int (or OperatorID, if using the above) then use a switch statement.
#property(nonatomic) OperatorID _operator;
Since you are already parsing the expression, this should be even easier / more straightforward to do.

i want to evaluate a math expression like y = 2(x * x) + 2.
But i need it in a loop, where the x changes maybe 100000 times.
You should consider using the TinyExpr math expression evaluation library. It is written in C, and will do exactly what you want. If you would prefer to code it yourself, TinyExpr is only 500 lines of code, so it's probably the simplest complete example you'll find.
Here's how you would solve your problem with x constantly changing:
double x;
te_variable vars[] = {{"x", &x}};
te_expr *expr = te_compile("2*(x*x)+2", vars, 1, 0);
for (x = 0; x < 100000; ++x) {
double y = te_eval(expr);
printf("x=%f, y=%f\n", x, y);
}
Note that the expression is automatically reevaluated with the present value of x, even though the expression is only "compiled" once.
If you need to be even faster, you could always generate code at run-time and then invoke an actual compiler. However, the time it takes to run the compiler would likely dwarf the speed savings until you're well into billions of evaluations. The 100,000 evaluation number you gave in your question would likely be evaluated almost instantly by TinyExpr. It's pretty fast.

You could get an existing expression parser. Some of them can "compile" such expressions on the fly to some internal format that would make evaluating the expression faster, and then allow you to provide it with values for the variables. The "compilation" would be done before the loop and the substitution once every loop iteration.
I know such expression parsers/evaluators exist for Delphi, but I don't know any for C, sorry. I assume you can find them online, as C has a far larger worldwide code base than Delphi. Just google (or bing, etc.) for "expression parser" and then look if the ones you found can do such substitutions without having to reparse the expression.

What's wrong with simply using OO design?
#implementation TreeNodeAdd
-(double)evaluateWithVariable:(double)x
{
return [left evaluateWithVariable:x] + [right evaluateWithVariable:x];
}
#end
...
- (double) evaluate:(TreeNode *)node variable:(double)x
{
return [node evaluateWithVariable:x];
}
The equivalent in C++ might be a little faster.

You cannot generate and execute machine code on iOS, but you can still do better than walking a parse tree. From the parse tree, generate instructions for a fictitious stack machine (think Forth, x87 machine code, java bytecode, CLR bytecode). While generating, you can determine how much stack space (numbers) you need. Then interpret these instructions for each value of x. This is faster because the instructions are more compact and have better locality than the parse tree and because no C recursion is used.
EDIT: For example, the expression sqrt(x+1) is translated to four instructions: one to push the variable x onto the stack, one to push the constant 1, one to pop the two numbers and push the sum and one to replace the sum with its square root. Any parse tree can easily be translated to such a list of instructions using a recursive function. An instruction could be represented by a struct containing an enum for the type of the instruction and a number for push constant instructions. The "stack" is not the C stack but simply an array of numbers with an integer that indicates how many are currently in use (which starts off as 0 and will end at 1).

Related

Why is passing pointer-pointers not motivated in Cocoa development?

When I pass a string the Apple-style way to a function and test it a billion times it takes ~ 42,001 seconds:
- (void)test:(NSString *)str {
NSString *test = str;
if (test) {
return;
}
}
NSString *value = #"Value 1";
NSLog(#"START");
for (int i = 0; i < 1e9; i++) {
[self test:value];
}
NSLog(#"END");
But then passing the pointer it's pointer as a value (assuming my test function will be read-only style) like so:
- (void)test:(NSString **)str {
NSString *test = *str;
if (test) {
return;
}
}
NSLog(#"START");
for (int i = 0; i < 1e9; i++) {
[self test:&value];
}
NSLog(#"END");
..only takes ~26,804 seconds.
Why does Apple promote the first example as normal practice, while the latter seems to perform so different?
I read about the Toll-Free Bridging that Foundation applies, but if the difference is relatively so big, what's the added value? A whole application that would run a factor of more than 100% faster by just upgrading some major function arguments like this, then isn't that a considerable flaw by Apple, in their way of instructing how to build apps in Objective-C?
You wouldn't use the NSString ** syntax, as that suggests that the method you're calling can change what value points to. You would never do that unless this is really what was taking place.
The simple NSString * example may be taking longer because in the absence of any optimization, the NSString * rendition is probably adding/removing of a strong references to value when the method is called and returns.
If you turn on optimization, the behavior changes. For example, when I used -Os "Fastest, Smallest" build setting, the NSString * rendition was actually faster than the NSString ** one. And even if the performance was worse, I wouldn't write the code that exposed me to all sorts problems down the line just because it was was 0.0000152 seconds faster per call. I'd find other ways to optimize the code.
To quote Donald Knuth:
Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. [Emphasis added]
The goal is always to write code whose functional intent is clear, whose type handling is safest and then, where possible, use the compiler's own internal optimization capabilities to tackle the performance issues. Only sacrifice the code readability and ease of maintenance and debugging when it's absolutely essential.

Why do I get the error "Array initializer must be an initializer list" when I'm trying to return this array in a function?

I am coming from Java, and I'm very new to Objective C. Anyway, I have this static method which is designed to make a copy of an array (if there's a better way to accomplish this, please let me know, but I'm asking this question more-so to find out why I got this error and how to avoid such an error in the future.) I ran into some problems with it, but just when I thought I had them all sorted out, I got this error that looked like
Here is the method in the interface:
+ (float[]) copyArray: (float[]) array withLength: (int) length;
And here is the method in the implementation:
+ (float[]) copyArray: (float[]) array withLength: (int) length
{
float copiedArray[length];
for (int i = 0; i < length; i++)
{
copiedArray[i] = array[i];
}
return copiedArray;
}
If all you really want is to copy the first n elements from one C array into another already existing array, probably the best way is to simply use memcpy:
memcpy(targetArray, sourceArray, sizeof(sourceArray[0]) * numElements);
The sizeof(sourceArray[0]) calculates the byte-size of the type in your array (in your case, it's equivalent to sizeof(float).
method/function cannot return C array. you should do this
+ (void) copyArrayFrom:(float *)array to:(float *)toArray withLength: (unsigned) length
{
for (int i = 0; i < length; i++)
{
toArray [i] = array[i];
}
}
C arrays are way more tricky than Java arrays. One of the biggest issues is that in a lot of instances, you don't know how large a C array is unless you have saved this information in a different variable, for example. The C FAQ "Arrays and Pointers" lists a lot of traps and they apply to Objective-C as well. You might want to see question 6.5 in particular.
As #lwxted already suggested, try to avoid C arrays unless you really know what you're doing and you have determined that you need them. C arrays are faster than NSArray but unless you have determined that your array really is a performance bottleneck by measuring with a profiler you will most likely not notice any difference.
And I strongly recommend avoiding a C array of Objective-C objects (id objects[]) unless you really, really know very well what you are doing (memory management issues).
In Objective-C, unless for particular needs, a better way to handle this usually is to use the NSArray as opposed to C arrays.
[NSArray arrayWithArray: array];
will copy an array.
Besides, in this case, if you insist on using C arrays, the use of implicitly typed length float[] is advised against. A better way is to use pointers to manipulate arrays.
Also, the stack-allocated array would be invalid after leaving the function, since it's local only in the scope of the copyArray function. You should dynamically allocate memory, if you wish the array to be valid outside the scope.
While I agree with all the points #DarkDust makes, if you're working with a C API such as OpenGL, there may be situations where using NSArray and NSNumber vs. C arrays of type float will have performance impacts. As always, try to use the simpler approach first, and carefully measure performance before deciding to optimize.
In any case, to answer the original question, here's how to correctly return a copy of a C array:
+ (float *)copyOfCArray:(float *)array withLength:(int)length
{
float *copyOfArray = malloc(length * sizeof(float));
for (int i = 0; i < length; i++) {
copyOfArray[i] = array[i];
}
return copyOfArray;
}
Also, there's arguably no need to make the above a method at all. Instead, consider writing it as a C function:
float *CopyArray(float *array, int length)
{
// Implementation would be the same...
}

Is it worth precomputing the conditional in a for loop?

Is there a difference between the following two code blocks in terms of the resulting machine code when using the llvm or gcc compilers?
When is this optimization actually worthwhile, if ever?
Not optimized:
for (int i=0; i<array.count; i++) {
//do some work
}
Optimized:
int count = array.count;
for (int i=0; i<count; i++) {
//do some work
}
EDIT: I should point out that array is immutable and array.count doesn't change during the loop's execution.
You really need to check it yourself. My guess is that there is a difference in the emitted code, but it might depend on compiler and compiler options, and it certainly can depend on the definition of array.
Nearly never, on the assumption that evaluating array.count is nearly always insignificant compared with "some work". The way to measure it, though, is to use a profiler (or equivalent) and observe what proportion of your program's runtime is spent at that line of code. Provided the profiler is accurate, that's the most you could hope to gain by changing it.
Suppose array.count is something really slow, that you happen to know will always return the same result but the compiler doesn't know that. Then it might be worth manually hoisting it. strlen gets used as an example. It's debateable how often strlen is actually slow in practice, but easy to manufacture examples likely to run slower than they need to:
char some_function(char a) {
return (a * 2 + 1) & 0x3F;
}
for (int i = 0; i < strlen(ptr); ++i) {
ptr[i] = some_function(ptr[i]); // faster than strlen for long enough strings.
}
You and I know that some_function never returns 0, and hence the length of the string never changes. The compiler might not see the definition of some_function, and even if it does see the definition might not realize that its non-zero-returningness is important.
The Steve Jessop answer is a good one. I just want to add:
Personally, I always use optimized version. It's just in my set of good practices to remove every constant component out of the loop. It's not much work and it makes code cleaner. It's not "premature optimization" and it does not introduce any problems or tradeoffs. It makes debugging easier (stepping). And it could potentially make the code faster. So it's a no-brainer to me.

Objective-C optimization

Are there standard optimization tricks for Objective-C to make for faster execution along the lines of "inlining" frequent methods as in C++ or the "g++ -fast" tag?
Edit: Does anyone have a short example using SEL and IMP when theMethod has two (or more) integers for input?
Here's a small optimisation that may not really be worth the time to implement, and one that I never use personally, but I guess still good to know about. Rather than repeatedly sending the same message to the same object over and over, you can bypass repeated method dispatch by directly using the method implementation. For example, instead of:
for (int i = 0; i < 100000000; i++)
[someObject messageWithInt:i];
You could try:
SEL theSelector = #selector(messageWithInt:);
IMP theMethod = [someObject methodForSelector:theSelector];
for (int i = 0; i < 100000000; i++)
theMethod (someObject, theSelector, i);
This means that the method lookup is only done once and you can invoke the method directly through the returned IMP value. All Objective-C method implementations take at least two arguments, the first argument is the receiving object of type id, which becomes self within the method implementation, and the second argument is the selector [of type SEL] that was used to determine the method implementation, and becomes _cmd in the method implementation.
This approach can quickly turn sour if you don't use the correct “function definition” (I can't remember the proper term). IMP is a typedef for a function that returns void* and takes (id,SEL,...) as arguments. This can make it troublesome to use if the method actually returns something else like float. To help with this matter, you can cast the return value of -methodForSelector:, like this:
typedef float (*MyMethodIMP)(id,SEL,int);
SEL theSel = #selector(messageWithInt:);
MyMethodIMP theMethod = (MyMethodIMP)[someObject methodForSelector:theSel];
float result = 0.0;
for (int i = 0; i < 100000000; i++)
result += theMethod (someObject, theSel, i);
With some care, you can save the theMethod and you may be able to use it for all instances of a particular class, not just one instance, but tread carefully.
Optimization is best handled by the compiler. Macs use GCC, so the standard optimization GCC flag (-Olevel) should work. In XCode, you can set the optimization level in the project settings. If you're not using GCC, check you compiler documentation for how to enable optimization.
Update: XCode 4 uses the LLVM backend by default. Both the GCC and clang frontends use "-On" optimization flags. For GCC, n is an integer from 0 through 3, or "s" or (Apple only) "z". For clang, n is an integer from 0 through 4, or "s".

Objective C - Which syntax?

What syntax do you think is better/more readable?
if(!myViewController.view.superview)
or:
if(myViewController.view.superview == nil)
Thanks!!
The two are very close, it comes down to personal taste or the conding standards of the project in question.
Saying !myViewController.view.superview meaning "no superview" is very clear.
Saying myViewController.view.superview == nil meaning superview is nil is also very clear.
I'd probably favor the former since if I was writing in English, I'd say:
if there is no superview then
I wouldn't say
if the superview is nothing then
But they are so close, and entirely equivalent, that it is hardly worth even being consistent with. Don't get me wrong, I'm all for consistency in general, it is just there really is no difference in readability between the two.
I use the second form because the intention is more clear that way.
Here is a link to Google's Objective C coding standards:
http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml
They don't explicitly say which way they prefer but they do say to only use nil for logic checks, of which your example above would qualify.
Personally for a long time I used the latter expression, but reversed. Using "foo == nil" (or nil == foo, to avoid bugs caused by forgetting one '=') is more pedantic. Eventually you will get tired of typing it, and the first version is also immune to the accidental nil assignment bug.
It's good for new coders to be verbose in what they're coding, as it provides practise at forcing them to think about what's really going on, but later, of course switch to a version that is faster if it is equivalent.
If for some insane reason, nil pointers were not 0 anymore, but some other invalid value (there's entire gigantic regions of memory which are invalid as pointers), then using '!' wouldn't work anymore, but that will never happen (or if it did, they'd add support to the compiler to overload '!' so that it meant "not invalid" when used with an object pointer and would do the right thing anyway, or else the Objective-C developers of the world would go crazy).
The only subtle problem with this is that it can start to train you to confuse the value of C's boolean expressions with the values of other types, which they aren't the same thing. So, if you start to think a boolean expression is just a BOOL, say, you might assume that assigning any non-zero value to a BOOL variable will do what you want, but it won't. Since a BOOL is just a char (currently), if you do something like:
- (BOOL)checkFoo {
BOOL foo = [bar count]; // imagine count is > 255
if(foo)
[self doSomething];
return foo;
}
where implicitly casting 256 or higher to BOOL gets you zero (NO) by truncation, not YES, which is what you want, versus
- (BOOL)checkFoo {
BOOL foo = ([bar count] > 0);
if(foo)
[self doSomething];
return foo;
}
or
- (BOOL)checkFoo {
if([bar count]) {
[self doSomething];
return YES;
}
return NO;
}
All I'm saying is, make sure you understand the background and the subtleties.