Question

Voici le code d'évaluateur d'expression très simple en utilisant IronRuby

public class BasicRubyExpressionEvaluator
{
    ScriptEngine engine;
    ScriptScope scope;
    public Exception LastException
    {
        get; set;
    }
    private static readonly Dictionary<string, ScriptSource> parserCache = new Dictionary<string, ScriptSource>();
    public BasicRubyExpressionEvaluator()
    {
        engine = Ruby.CreateEngine();
        scope = engine.CreateScope();

    }

    public object Evaluate(string expression, DataRow context)
    {
        ScriptSource source;
        parserCache.TryGetValue(expression, out source);
        if (source == null)
        {
            source = engine.CreateScriptSourceFromString(expression, SourceCodeKind.SingleStatement);
            parserCache.Add(expression, source);
        }

        var result = source.Execute(scope);
        return result;
    }
    public void SetVariable(string variableName, object value)
    {
        scope.SetVariable(variableName, value);
    }
}

et est problème.

var evaluator = new BasicRubyExpressionEvaluator();
evaluator.SetVariable("a", 10);
evaluator.SetVariable("b", 1 );
evaluator.Evaluate("a+b+2", null);

vs

var evaluator = new BasicRubyExpressionEvaluator();
evaluator.Evaluate("10+1+2", null);

Première 25 fois plus lent que seconde. Aucune suggestion? String.Replace est pas une solution pour moi.

Était-ce utile?

La solution

Je ne pense pas que les performances que vous voyez est dû au réglage variable; la première exécution de IronRuby dans un programme est toujours va être plus lente que la seconde, quel que soit ce que vous faites, puisque la plupart du compilateur n'est pas chargé jusqu'à ce que le code est exécuté en fait (pour des raisons de performances de démarrage). S'il vous plaît essayer cet exemple encore une fois, peut-être en cours d'exécution chaque version de votre code dans une boucle, et vous verrez la performance est à peu près équivalent; la version variables a une certaine surcharge de méthode pour obtenir l'envoi des variables, mais cela devrait être négligeable si vous avez assez.

En outre, dans votre code d'hébergement, la façon dont vous venez tenez sur ScriptScopes dans un dictionnaire? Je tiendrais sur place CompiledCode (résultat de engine.CreateScriptSourceFromString (...) Compile ().) -. Comme cela aidera beaucoup plus dans les courses de répétition

Autres conseils

vous pouvez bien sûr d'abord construire la chaîne quelque chose comme

evaluator.Evaluate (string.format ( "a = {0}; b = {1}; a + b + 2", 10, 1))

Ou vous pouvez faire une méthode

si au lieu de votre script vous retournez une méthode alors vous devriez pouvoir l'utiliser comme un objet régulier C # Func.

var script = @"

def self.addition(a, b)
  a + b + 2
end
"

engine.ExecuteScript(script);
var = func = scope.GetVariable<Func<object,object,object>>("addition");    
func(10,1)

Ceci est probablement pas un extrait de travail, mais il montre l'idée générale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top