c# - Are delegates created via lambda expressions guaranteed to be cached? -


it seems working way, stated somewhere in spec or implementation detail can't depend on? i'm trying speed property/field name extraction faster creating expression tree once , caching it. wrapping tree in lambda , using key cache. , break down miserably if runtime decides create new delegate every time hits same lambda expression.

// keyvaluepair<string, t> getpair<t>(func<expression<func<t>>> val)... var item = new item { num = 42 }; var pair = getpair(() => () => item.num); // guaranteed same instance? // pair.key = "num" // pair.value = 42 

edit: ok, here full thing. seems works , doesn't seem generate garbage in process.

another edit: ok, changed it, doesn't seem capture anything, , works faster!

using system; using system.diagnostics; using system.linq.expressions; using system.runtime.compilerservices;  class program {     static void main(string[] args) {         var pair = new pair<int>();         var pair2 = new pair<string>();         var item = new item { num = 42, word = "answer" };         double ratio = 1;         var sw = stopwatch.startnew();         (int = 0;; i++) {             if ((i & 0xfff) == 0 && sw.elapsedmilliseconds > 2000) {                 console.writeline("literal: {0:n0}", i);                 ratio *= i;                 break;             }             assign(pair, "num", item.num); assign(pair2, "word", item.word);             assign(pair, "num", item.num); assign(pair2, "word", item.word);             assign(pair, "num", item.num); assign(pair2, "word", item.word);             assign(pair, "num", item.num); assign(pair2, "word", item.word);         }         sw = stopwatch.startnew();         (int = 0; ; i++) {             if ((i & 0xfff) == 0 && sw.elapsedmilliseconds > 2000) {                 item = new item { num = 42, word = "answer" };                 console.writeline("expression: {0:n0}", i);                 ratio /= i;                 break;             }             assign4(pair, item, () => => it.num); assign4(pair2, item, () => => it.word);             assign4(pair, item, () => => it.num); assign4(pair2, item, () => => it.word);             assign4(pair, item, () => => it.num); assign4(pair2, item, () => => it.word);             assign4(pair, item, () => => it.num); assign4(pair2, item, () => => it.word);          }         console.writeline(ratio.tostring("f3"));         console.readline();     }      static void assign<t>(pair<t> pair, string name, t value) {         pair.name = name;         pair.value = value;     }      static void assign4<t, u>(pair<t> pair, u item, func<expression<func<u, t>>> value,         [callerfilepath]string path = "", [callerlinenumber]int line = 0) {          int key = ((path.length << 20) + line) % cache<u, t>.length; //        int key = value.gethashcode() % cache<t>.length;         while (true) {             var bucket = cache<u, t>.records[key];             if (bucket.literal == null) break;             if (object.referenceequals(bucket.literal, value)) {                 pair.name = bucket.fieldname;                 pair.value = bucket.getter(item);                 return;             }             key += 1;             if (key == cache<u, t>.length) key = 0;         }         var tree = value();         var getter = tree.compile();         string name = (tree.body memberexpression).member.name;         cache<u, t>.records[key] = new cache<u, t>.record {             literal = value,             fieldname = name,             getter = getter,         };         pair.name = name;         pair.value = getter(item);     } }  class cache<u, t> {     public struct record     {         public func<expression<func<u, t>>> literal;         public string fieldname;         public func<u, t> getter;     }     public const int length = 997;     public static record[] records = new record[length]; }  class pair<t> {     public string name;     public t value; }  class item {     public int num;     public string word; } 

it can't same instance in case - captured variable (item) different each time execute pair of lines.

even can same instance, isn't guaranteed. remember of ms c# compiler, lambda expressions don't capture any variables (not this) cached in static variables - i'm not sure else is.


Comments

Popular posts from this blog

c++ - Creating new partition disk winapi -

Android Prevent Bluetooth Pairing Dialog -

php - joomla get content in onBeforeCompileHead function -