数学前pression评价 - 非常快 - 与Objective-C的 [英] math expression evaluation - very fast - with objective-c

查看:138
本文介绍了数学前pression评价 - 非常快 - 与Objective-C的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要评价一个数学前pression像Y = 2(X * X)+ 2

i want to evaluate a math expression like y = 2(x * x) + 2.

但我需要它在一个循环中,其中x的变化,也许10万次。

But i need it in a loop, where the x changes maybe 100000 times.

我已经写了code来翻译语法树前pression。

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;
}

有人说:如果我得走了速度,我可以翻译前pression到C code,编译并将其链接到的即时一个DLL和加载(大约需要一秒钟) 。的数学函数这样,再加memoized版本,可以给我最好的性能。

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.

我怎么能achive吗?
我怎样才能编译数学前pression到C code和汇编,并将其链接到一个dll左右。然后加载它的飞行,以加快循环了?

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 ?

非常感谢!

克里斯

推荐答案

我的建议是:不要写这个code自己。写过code,它这样做,有一些事情需要注意的:

My advice: Do not write this code yourself. Having written code that does this, there are some things to be aware of:

解析数学EX pressions不是一个简单的问题,如果你要正确,充分做到这一点。你必须要考虑的事情就像每个运营商的关联性:如果发现同一个运营商的多个在离pression会发生什么?哪一个你先评估?你如何处理与运营商的precedence取决于他们的环境的变化? (例如,反)这些都是难以回答的问题,只有极少数的实现得到它的权利。

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:


  1. NS predicate 。优点:内置,相当快的,体面的precision。缺点:指数解析不正确的关联性,不能扩展,不支持隐式的乘法运算(即 2(X * X)),不正确分析反运算。

  2. GCMathParser 。优点:的非常快的,体面的precision。缺点:不能扩展,不支持隐式的乘法,不能正确分析否定运算符

  3. DDMathParser 。优点:优秀的precision,可扩展的,支持隐式乘法。缺点:不太一样快,另外两个,由于分析引擎和高precision数学

  1. 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.
  2. GCMathParser. Pros: very fast, decent precision. Cons: not extensible, does not support implicit multiplication, does not parse the negation operator correctly.
  3. 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

显然,我建议 DDMathParser (我写的)。在你的情况,你会想要做这样的事情:

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 可在GitHub上: https://github.com/davedelong/ DDMathParser 的。请留心其许可证(自由与归属使用)。

DDMathParser is available on GitHub: https://github.com/davedelong/DDMathParser . Please be mindful of its license (free for use with attribution).

不过,如果你真行与牺牲一些precision(一对夫妇它是不正确的情况下),以换取超快的速度,我推荐使用的 GCMathParser

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.

这篇关于数学前pression评价 - 非常快 - 与Objective-C的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆