Faktisk har jeg en stavl af disse funtioner. Ideen er at jeg laver en dynamisk funktion (DynamicMethod og indsaetter de aktive filtre i denne funktion vha IL. Hvis jeg har 300 filtre, men kun 20 er sat, saa bliver kun 20 indsaet i den dynamiske metode hvilket giver stor forbedring i hastighed. Naa nok om det.
Denne funktion kan laves som foelgende i IL (taget fra ILDASM):
(I det kommende vil jeg bruge push og pop hvilket er en forkortelse for "push to stack" og "pop from stack")
1) LocalBuilder b = generator.DeclareLocal(typeof(DateTime)); // Create local variable 2) generator.Emit(OpCodes.Ldarg_0); // Push Datarow (argument 0) 3) generator.Emit(OpCodes.Ldstr, "test"); // Push string 4) generator.EmitCall(OpCodes.Callvirt, mGetItemMethodInfo, null); // Pop DataRow, pop string, calls Item["datacolumnName"] and Push result 5) generator.Emit(OpCodes.Unbox_Any, typeof(DateTime)); // Pop boxed DateTime, unbox it, and push unboxed DateTime 6) generator.Emit(OpCodes.Stloc, b.LocalIndex); // Pops Datetime and stores it in local variable 7) generator.Emit(OpCodes.Ldloca, b.LocalIndex); // Retrieves Datetime from local variable and push 8) generator.Emit(OpCodes.Call, mi); // Pop DateTime, calls get_Ticks and push result 9) generator.Emit(OpCodes.Ldc_I8, value.Min.Value.Ticks); // Push constanst
...... Compare the two values on the stack returning true/false depending on values ......
Alt sammen er fint - det virker. Det eneste jeg ikke forstaar er 6 og 7 (og 1). Hvis jeg fjerner disse faar jeg en fejl vedr. ustabilitet. Er der nogen der kan forklare HVORFOR disse 2 skal vaere der?
1) Erklærer en lokal variabel (altså på stakken) af typen DateTime. 6) Gemmer den unboxede version af resultatet fra dit metodekald i 4. DateTime er en value type. 7) Henter indholdet af den lokale variabel så den kan bruges som input til metodekald i 8.
Brian>> Jeg finder det meget maerkeligt eftersom 6 og 7 kun fjerner og derefter propper DateTime tilbage paa stacken, dvs. stacken ser ens ud foer 6 og efter 7. Hvorfor er det saa noedvendigt?
I 6 popper stloc din variabel fra stakken og gemmer den i din lokale variabel. Da værdien således ikke længere er på stakken skal den derfor pushes igen i 7, inden den kan bruges i 8.
Du kan læse om de enkelte IL-instruktion i "Common Language Infrastructure (CLI) Partition III CIL Instruction Set".
Brian>> Jeg tror der er en misforstaaelse af hvad spg. egentlig er. Lidt klasificering:
Jeg er ikke i tvivl om hvad 6 og 7 goer. Problemet er at jeg ikke forstaar hvorfor de ikke kan udelades. 6 fjerner vaerdien fra stakken, og 7 propper den tilbage paa stakken. Dvs. disse 2 operationer efterlader stakken i samme position - foer som efter. Hvorfor SKAL det goeres? Hvorfor kan det ikke udelades?
Ah - du har ret, det havde jeg ikke set. Men i så fald er svaret, at unbox_any efterlader værdien på stakken i stedet for en reference til denne, mens ldloca pusher adressen på den lokale variabel på stakken, så skønt begge instruktioner arbejder på samme variabel, gør de ikke det samme og derfor kan du ikke blot fjerne 6 og 7. Håber det giver mening.
Brian>> Det giver mening. Tak. Saa skulle jeg mene at 5, 6 og 7 kunne fjernes? (da 5 netop laver en unboxed version af DateTime, hvorefter 6 og 7 boxer den igen)
Nu kan jeg ikke se ud af dit eksempel hvad mGetItemMethodInfo indeholder, men jeg vil antage, at grunden til, at der bliver unboxed, er at din indexer returnerer en referencetype, der skal gemmes i den lokale variabel, og derfor har du vel brug for den unbox. Hvorfor vil du fjerne instruktioner?
Jeg ser ingen grund til at gemme vaerdien i en lokal variable, men da det fejler ved fjerning, saa har jeg nok ikke forstaaet IL koden helt. Dette spg er kun til at forstaa IL'en bedre; altsaa hvorfor SKAL jeg gemme det i en lokal variable for at det virker.
Kodehoved>> hvad mGetItemMethodInfo indeholder
mGetItemMethodInfo er getter method paa en DataRow
Jeg kan desvaerre stadig ikke se det, men lad mig kigge lidt paa og vende tilbage.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.