Understanding the cost of DLLs

I am attempting a project that uses DLLs as a means of having a dynamic object factory. In other words, I have a bunch of concrete classes derived from a single abstract class, but I do not know what actual class I am using until run-time. Instead of creating a large switch statement that has to be modified each time I make a new derived class, I create a new DLL for each derived class. Each DLL provides an interface function that when invoked returns an instance of the derived object. So, instead of a large switch statement, I just load the DLL based on a file name and get the interface function every time.

The heart of the problem is that I wanted to test the overhead incurred when using the DLL objects instead of the hardcoded ones. To do so, I threw in a large for loop into one of the object functions that called pow(rand(), 3) 50000 times. I then profiled the two versions. To my surprise, using the AQ time profiler, after 500 (or 500*50000 = 2.5M rand calls) tests, the total time that the program spent in the rand() call when using DLLs was more than twice the time spent in rand() when not using DLLs.

Is there any easy explanation to this? I am very new to DLL usage, but I was not aware of any reason why calling rand from with a DLL created object would incur so much more overhead than a call from a non-DLL object. Perhaps my testing methodology is wrong? I am currently using VC++ 6.0 with the STLPort 4.6.2 libraries (since the MS STL does not support passing STL objects from a program to a DLL function, which is a requrement for some of the functoins in my objects).

Any help would be greatly appreciated!
[1669 byte] By [liquidroyl] at [2007-11-19 0:22:47]
# 1 Re: Understanding the cost of DLLs
Did you make 500 calls to LoadLibrary as well?
gradiov at 2007-11-11 0:55:42 >
# 2 Re: Understanding the cost of DLLs
Yes -- as part of the test I iteratively opened and closed the library as well. Would this adversely affect the functions called from within an object created by the library? It was not the overall run time that doubled, it was the time spent specifically in rand().
liquidroyl at 2007-11-11 0:56:42 >
# 3 Re: Understanding the cost of DLLs
Yes -- as part of the test I iteratively opened and closed the library as well. Would this adversely affect the functions called from within an object created by the library? It was not the overall run time that doubled, it was the time spent specifically in rand().
You never mentioned whether you are timing release or debug versions of the DLL. You should always time a release version of the DLL and application.

Regards,

Paul McKenzie
Paul McKenzie at 2007-11-11 0:57:43 >
# 4 Re: Understanding the cost of DLLs
I made additional runs w/o the new/delete or loadlibrary/freelibrary calls in the loop, and the results were still the same. Here are my runs:

Object created with "new":
Run time time w/ children time
1 (single creation): 2.57 2.57
2 (new each iteration) 2.77 2.77
3 " " " 1.46 1.46

Object created using DLL:
Run time time w/ children
1 (single create) 5.20 7.46
2 (new each iter) 4.49 6.57
3 " " " 2.95 5.51

Each run number corresponds to the run for the other case; that is, run 3 of the first test was run directly after run 3 of the second test, run 2 after run 2, etc.
The main thing to notice is not only are the times in general longer for the object created using the DLL, but rand's time spent w/ its children functions is also longer. Any intuition / ideas?
liquidroyl at 2007-11-11 0:58:49 >
# 5 Re: Understanding the cost of DLLs
I dunno, but am wondering if this has to do something with the code in the dll being in a different page which the OS may have to swap to execute.
kirants at 2007-11-11 0:59:47 >
# 6 Re: Understanding the cost of DLLs
I realized I was doing timings for debug release and ran additional tests in release mode.

Time spent on pow(rand(), 3) line:

Using default optimization:

Using "new"
Test 1:
11.08
11.08 w/ children

Using DLL:
Test 1:
12.44
12.44 w/ children

Using /O2 optimization:

Using "new"
Test 1:
10.67
10.67 w/ children

Using DLL:
Test:
11.71
11.71 w/ children

So the time w/ and w/o child discrepancy between the 2 options is no longer apparent in release mode, but the overal time discrepency is still there. Ideas?
I've been reading up in between responses on general DLL info but it's been difficult finding much mention of time costs. To me it seems like 10% increased overall time is a little high, but I have no idea what to really compare it against.
liquidroyl at 2007-11-11 1:00:44 >
# 7 Re: Understanding the cost of DLLs
Maybe you should look at the code generation for the call to rand() in the application version, and the rand() in the DLL. If the assembly for both are different, then you will get different timings.

Why the assembly would be different? Could mean that you are using different run-time libraries for DLL and application, or some other reason that I can't think of at the moment. If the assembly is the same, it could be more to do with some swapping or something else that is OS related.

Regards,

Paul McKenzie
Paul McKenzie at 2007-11-11 1:01:48 >
# 8 Re: Understanding the cost of DLLs
Thanks for the advice Paul! I changed the runtime library for the DLL to be singly-threaded (thus matching the RTL for the other test) and the overhead for using the DLL went from 10% down to 1%, which is a small enough difference to be acceptable.
liquidroyl at 2007-11-11 1:02:46 >