È possibile generare un'identità di un delegato per distinguerlo da altri delegati? Pensate a questo codice:Possiamo ottenere un'identità di un delegato?
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);
Il problema che voglio risolvere è, voglio mettere in cache una certa JIT compilato il codice GPU in .NET. Per rendere più facile da usare, voglio lasciare all'utente di inviare l'delegato, e se il delegato è lo stesso, cerchiamo di scoprire il codice GPU da una cache, piuttosto che JIT compilare esso ogni volta:
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 possibile soluzione è quella di confrontare la stringa di espressione, ma ha ancora un problema per prendere il Clouser, come ad esempio:
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();
come sottolineato grazie @SWeko e @Luaan, nell'esempio precedente, delegate1
e delegate2
sono in realtà lo stesso. Ma lo scopo della cache il delegato è il seguente utilizzo:
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!
Forse è possibile utilizzare [Alberi di espressione] (https://msdn.microsoft.com/en-us/library/bb397951.aspx) invece di 'Func'. Non sono sicuro che implementino 'Equals' e' GetHashCode' come richiesto, ma tu puoi scorrere la struttura e puoi creare il tuo HashCode - ma non è così semplice come sembra. - E non sono sicuro che ciò comporterà un vantaggio in termini di prestazioni. –
@Verarind quindi possiamo creare un albero di espressioni da un delegato, ma poi di nuovo la domanda, possiamo semplicemente confrontare l'equità di due oggetti dell'albero dell'espressione? –
I tuoi delegati * non sono * gli stessi. Ispezionare 'delegate1.Method'. Ispeziona 'delegate2.Method'. Sono due funzioni diverse che capita di fare la stessa cosa. Chiedi l'identità di un delegato, ma il tuo codice lo rileva già correttamente. Quello che ti interessa davvero è qualcos'altro. – hvd