Frage

Hier ist der Code von sehr einfacher Ausdrucksauswertung mit 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);
    }
}

und hier ist Problem.

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

Erste 25-mal langsamer als zweite. Irgendwelche Vorschläge? String.Replace ist keine Lösung für mich.

War es hilfreich?

Lösung

Das glaube ich nicht die Leistung, die Sie ist durch variable Einstellung sehen; die erste Ausführung von IronRuby in einem Programm sein wird langsamer immer als der zweite, unabhängig davon, was Sie tun, die meisten der Compiler da in nicht geladen, bis Code ausgeführt tatsächlich (aus Gründen Startleistung). Bitte versuchen, dieses Beispiel wieder, vielleicht jede Version des Codes in einer Schleife ausgeführt wird, und Sie werden die Leistung sehen in etwa gleichwertig ist; die Variable-Version einige Overhead-Methode-Versand hat die Variablen zu bekommen, aber das sollte vernachlässigbar sein, wenn Sie es genug laufen.

Auch in Ihrem Hosting-Code, wie kommt man auf ScriptScopes in einem Wörterbuch halten? Ich würde halten auf CompiledCode statt (Ergebnis des engine.CreateScriptSourceFromString (...) Kompilieren ().) -. Wie das wird viel mehr in Wiederholungsläufen helfen

Andere Tipps

Sie können natürlich zuerst die Zeichenfolge so etwas wie

bauen

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

Sie können es auch ein Verfahren machen

, wenn anstelle des Skripts Sie eine Methode zurückkehren, dann sollten Sie in der Lage sein, es zu benutzen wie ein normales C # Func-Objekt.

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)

Dies ist wahrscheinlich kein Arbeits Schnipsel, aber es zeigt die allgemeine Idee.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top