Возможно ли генерировать idenitity делегата, чтобы отличить его от другого делегата? Подумайте об этом коде:Можем ли мы получить личность делегата?
Func<int, int, int> delegate1 = a, b => a + b;
Func<int, int, int> delegate2 = a, b => a + b;
Func<int, int, int> delegate3 = a, b => a - b;
let id1 = id(delegate1);
let id2 = id(delegate2);
let id3 = id(delegate3);
Assert(id1 == id2);
Assert(id1 != id3);
Проблема, которую я хочу, чтобы решить, я хочу, чтобы кэшировать некоторые JIT скомпилированный код GPU в .NET. Для того, чтобы сделать его легко использовать, я хочу, чтобы пользователь послать делегата, и если делегат же, мы пытаемся выяснить код GPU из кэша, а не JIT скомпилировать его каждый раз:
Parallel(outputA, inputA1, inputA2, a, b => a + b); //should JIT compile GPU code, and cache it by its identity
Parallel(outputB, inputB1, inputB2, a, b => a + b); //should NOT JIT compile GPU code, and use the cached GPU code by its identity
One возможным решением является сравнение строку выражения, но она все еще имеет проблемы, чтобы поймать Клоузер, такие как:
int c = 0;
Expression<Func<int, int, int>> delegate1 = (a, b) => a + b + c;
c += 1;
Expression<Func<int, int, int>> delegate2 = (a, b) => a + b + c;
Expression<Func<int, int, int>> delegate3 = (a, b) => a - b - c;
Console.WriteLine(delegate1);
Console.WriteLine(delegate2);
Console.WriteLine(delegate1.ToString() == delegate2.ToString());
Console.ReadKey();
Как уже указывалось, благодаря @SWeko и @Luaan, в приведенном выше примере, delegate1
и delegate2
на самом деле тоже самое. Но цель кэширования делегатов в следующем использовании:
int c = 1;
Parallel(outputA, inputA1, inputA2, (a,b) => a+b); //do JIT compile of GPU code
c += 1;
Parallel(outputB, inputB1, inputB2, (a,b) => a+b); //as the delegate is same then the previouse one, it will not do JIT GPU code compiling, but then, that is wrong!
Возможно, вы можете использовать [Деревья выражений] (https://msdn.microsoft.com/en-us/library/bb397951.aspx) вместо 'Func'. Я не уверен, что они реализуют «Equals» и «GetHashCode» по запросу, но вы можете выполнять итерацию по структуре, и вы можете создать свой собственный HashCode, но это не так просто, как кажется. - И я не уверен, что это приведет к повышению производительности. –
@Verarind, тогда мы можем создать дерево выражений из делегата, но опять же вопрос, можем ли мы просто сравнить equaliaty двух объектов дерева выражений? –
Ваши делегаты * не * одинаковы. Проверьте 'delegate1.Method'. Осмотрите 'delegate2.Method'. Это две разные функции, которые выполняют одно и то же. Вы спрашиваете о личности делегата, но ваш код уже правильно определяет это. То, что вас действительно интересует, - это что-то еще. – hvd