Using Roslyn to create predicate from string is very slow

Viewed 190

Using Microsoft.CodeAnalysis.CSharp.Scripting I have created a generic method to turn a string into a predicate:

public static Func<T, bool> CreatePredicate<T>(string command)
{
    var options = ScriptOptions.Default.AddReferences(typeof(T).Assembly);
    Func<T, bool> predicate = CSharpScript.EvaluateAsync<Func<T, bool>>(command, options).Result;

    return predicate;
}

The problem is that this is very slow. It takes 3-4 seconds to generate the predicate.

Is there a way to turn a string into a predicate faster using Roslyn? (I am aware of alternative of manually creating expression using Expression class, this question is specifically at doing this with Roslyn)

Here is stadalone example:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;

namespace DynamicLambda
{
    class Program
    {
        static void Main(string[] args)
        {
            var albums = new List<Album>
            {
                new Album { Quantity = 10, Artist = "Betontod", Title = "Revolution" },
                new Album { Quantity = 50, Artist = "The Dangerous Summer", Title = "The Dangerous Summer" },
                new Album { Quantity = 200, Artist = "Depeche Mode", Title = "Spirit" },
            };

            var albumFilter = "album => album.Quantity > 20 && album.Quantity < 200";

            var sw = new Stopwatch();
            sw.Start();
            var predicate = CreatePredicate<Album>(albumFilter);
            sw.Stop();

            var filteredAlbums = albums.Where(predicate).ToList();
        }

        public static Func<T, bool> CreatePredicate<T>(string command)
        {
            var options = ScriptOptions.Default.AddReferences(typeof(T).Assembly);
            Func<T, bool> predicate = CSharpScript.EvaluateAsync<Func<T, bool>>(command, options).Result;

            return predicate;
        }
    }

    

    public class Album
    {
        public int Quantity { get; set; }
        public string Title { get; set; }
        public string Artist { get; set; }
    }

    
}
0 Answers
Related