Weird Performance Differences of PRG vs. EXE vs. COM Object in Large Apps
June 11, 2008 •
I was working recently with a customer and we were reviewing performance of an application we were in the process of building with Web Connection. During development the performance was horrible, some of it due to data issues a few others for the code paths through various application layers as this application is a port of a desktop app that doesn't concern itself with stateless issues. We were able to tweak the app itself some to improve data and application performance but requests were still very slow overall.
PRG file Execution compared to EXE Execution
We were working in the IDE and performance was pretty bad with requests taking 3-5 seconds and more at times which is terrible for a Web application. I then compiled the application, set all the deployment options for the app (turned off Debug mode, set the Page compilation to Run only) and we then ran the application from the EXE. To my surprise performance response times ended up being nearly a third of the IDE speed. I re-ran the PRG based files in the IDE and dropped right back to the original slowness.
Now typically when I run Web Connection applications I run them as PRG files. I start the main PRG file and execute the code that way. This is quicker during development as you can skip the compile process which was slow for this particular business object implementation plus business logic which is approaching 10 megs for the final compiled EXE (large app + about 800k for Web Connection base libs).
But I've never really noticed just how much worse performance can be in the IDE vs running the EXE. To check I also tried the same thing with my own Web Connection demo server and sure enough I saw the same performance differences between IDE and EXE – although the difference in that app was more with 2x as fast in the EXE.
I'm a bit baffled. Maybe this behavior is new in VFP 9 because I do remember a time when I ran applications in the IDE with PRGs and they ran just as fast as in an EXE. I did turn off any options – including the critical SET RESOURCE OFF which often can be the worst perf culprit – but I was unable to reduce request times when running PRG files, which just seems odd. I also turned off DEVELOPMENT, DEBUG, TALK, STATUS, NOTIFY all of which have some effect on perf, but same reasult. There's no reason that PRG files should be THIS much slower after the initial PRGs/VCX classes have been loaded into memory.
The main difference between a compiled app and local files is that there's no file lookup, but once everything has been loaded from disk – it seems odd that there should be any difference in performance. Yet there it is.
COM vs. File execution on a huge Executable
It gets stranger yet though: with this customer we also tried running the application as a COM server so we simply switched the app into COM mode through the Web Connection admin panel and ran that way. To my big surprise we also found that the COM server was significantly SLOWER executing the same requests that the EXE file based server was running. Perf was still significantly faster than IDE PRG operation, but somewhere in the middle between that and the file based EXE.
Now mind you I'm talking about FoxPro request times here, running single requests. This isn't in response to load testing where other factors weigh in. Here the perf differences are merely measuring the actual processing time inside of the FoxPro code that executes and in this case COM operation is significantly slower.
I then set up my Web Connection sample server in COM mode and compared to file mode and found – roughly the same performance as the file based EXE server.
So WTF is going on here?
I don't have any answers, but I think the reason for the drastically slow performance probably has something to do with load times of libraries due to the size of the base application. In the customers application there is a huge number of libraries both PRG and VCX that are being used. A COM server loads all those libraries up front (COM servers do an implicit SET CLASSLIB TO all VCX files and PRG Classes) even those that aren't used. The standalone EXE only loads what you set Procedure/Classlib to and then dynamically loads the rest of the libraries so there's probably much less searching going on to find the relevant components. But that's just a guess.
I suspect the size of this application is triggering some sort of internal limit in VFP and as a result causes slow behavior. The slow perf is observable right from the Command window so this has nothing to do with Web Connection, but it's troubling nevertheless.
Has anybody seen this behavior behavior before where you have a HUGE COM object with a large number of classes (over 1000 and a couple of hundred source files) and then see slow operation in COM objects?
Frankly I'm baffled and this is the first app where I've seen this behavior. It's especially pronounced because the backend application happens to be on the slow side since it's optimized for a desktop environment (which is being addressed, but it'll take time). There will also be some paring down of the libraries to only provide those libraries that are actually used which should
Christof Wollenhaupt
June 11, 2008