Urgent Help Needed

Aug 11, 2010 at 11:39 PM
Edited Aug 11, 2010 at 11:49 PM

Hi. I decided to use fasterflect because I had major speed problems when running dynamic code and will be running each piece of code in a loop millions of times. I first decided to save the dynamically created code in dlls because the first execution of the code was rediculously slow and I thought having the code precompiled would elliminate this, but that did not help and with the fasterflect Cache API it's still way too slow but only for the first execution. It takes about 18 seconds and the file is only 555kb. When I release my program the user may create several dlls and they could be a lot larger. I cannot have the program hang for minutes every time it starts. Any assistance on getting this time down would be greatly appreciate. I don't want the user to wait more than a couple of secconds. The class in the dlls and the function to call is know at compile time, just the name off the dlls and the exact content isn't.

Aug 12, 2010 at 11:14 AM
Dynamic methods need to be JIT compiled from CIL into native processor instructions, and this is why the first execution is much slower. There are a couple of strategies for avoiding or minimizing this initial hit, most notably: 1) Spawning a background thread to trigger the JIT compilation, so that the compilation delay does not need to be paid later. Mostly useful if the code does is not needed during application startup. 2) Generating assemblies instead of dynamic methods, possibly using ngen.exe to precompile the assembly. Look to Mono.Cecil instead of Fasterflect if this is what you need. Not sure what exactly you're trying to accomplish, so if you're still in doubt please provide additional insight into what you're doing.
Aug 12, 2010 at 2:07 PM
Edited Aug 12, 2010 at 2:55 PM

My program is a profile simulator for Shanky's Holdem bot. It allows the user to play poker against bots manualy, run simulations over millions of hands and play tournaments. The profiles have to be dynamically converted into C# whenever any changes are made to them and of course the user will be using his own profiles and not have access to my source code, so it must all happen dynamically. I was hoping the compiling process could however, be saved, so if the user closes the program then starts it again he can carry on with the same game without any delay, provided he hasn't modified any profiles currently in use.

Aug 13, 2010 at 12:56 PM
I'm not aware of any mechanism that allows you to save a dynamic method to an assembly, so that it can be loaded into a different AppDomain (e.g. for restarting the application). As such, if this is what you want to support then you should look at Mono.Cecil, which afaik allows for many advanced IL and assembly generation techniques. If saving to disk is not needed then Fasterflect should suffice. You should use the delegate API and keep a reference to the generated dynamic method rather than calling the cached API, since the cache lookup itself is somewhat costly when you have lots of repeated calls to the same delegate. JIT compilation occurs only for the first invocation of the delegate and after that you should see native speeds. Although JIT compilation is slow, unless you have an unreasonable amount of methods I doubt that it will be noticeable when distributed over millions of invocations.
Aug 13, 2010 at 3:10 PM
Edited Aug 13, 2010 at 4:32 PM

Thank you for your help. The delegate API will cetainly do for performing simulations. The only problem is when playing a regular game or tourney the user will have to wait for a lengthy period even when they're just continuing the same game that's auto loaded. I guess I'll just have to make do with that. I had a brief look at Mono.Cecil and I don't even know where to begin with that. There must be another way. Do you think if I upgraded to Visual Studio 2010 and installed .Net 4.0 that would help? I am currently using Visual Studio 2008 with .Net 3.5.

Aug 13, 2010 at 3:34 PM
Upgrading is unlikely to help, although it will improve the performance of Fasterflect's cached API slightly (due to new concurrent collections in the framework). Have you used a profiler to investigate the performance? 18 seconds is quite a lot of time, although it wasn't particularly clear from you first post exactly what was happening in that amount of time.
Aug 13, 2010 at 4:51 PM

No I've not used a profiler to investigate performance. To be honest I've never used a profiler, but I'll have a go with one and see if that helps with any performance issues. Basically the 18 secconds is the time it takes for the first execution of a single profile of length 555kb. This is after it has been converted from PPL code into C# code and the time is about the same regardless of whether it's loading from a DLL file or getting the code from a text file.