I'm updating ExcelListener.vcx to take advantage of Greg Green's excellent class vfpxWorkbookXlsx.vcx, which creates Excel files with xlsx format.
To optimize speed I want to make sure cursors remain in memory only. I believe this is the default VFP behavior, but am confused by the fact that you can append from a cursor by referring to it as APPEND FROM DBF('CursorName') and the fact that that that file actually exists on disk.
I'd appreciate any clarifications. No need for ram disks, right?
TIA,
Alex
No - they are always backed by a file (in TMPFILES
by default - you can check there to see the cursors). It's possible most if not all of the file may end up being buffered in memory but there's no guarantee. FoxPro optimizes memory usage to what works best - binary tree indexes first and if there is space parts of the actual table that were last used. How much that is depends on how much memory FoxPro has available in the process.
If you want things to stay completely in memory use Collections or Arrays, but performance of manipulating those is actually considerably worse than manipulating Cursors, except for very small sets.
I don't think you have to worry much about performance with cursors/tables, unless you have very large tables that reach FoxPro's size limits or you are doing a lot of non-Rushmore optimized searches.
As a general rule cursors are the fastest in most cases to deal with structured data.
+++ Rick ---
Thank you Rick. Will double check indexes.
Alex
I cannot add to what Rick has described - but of course it is possible to use a RAM disk for your tmpfiles directory if you really need top speed. Of course, you need to steal Windows memory to use as a RAM disk so it may not be worth the effort: https://www.howtogeek.com/171432/ram-disks-explained-what-they-are-and-why-you-probably-shouldnt-use-one/
RAM disks were a thing once, but Windows does internal caching of files that's way more efficient than what you'd get with a RAM drive today. This is especially true with today's fast SSD drives and drive caches.
In short - almost never worth the effort.
+++ Rick ---
FWIW, you can run this function periodically to clear memory used by VFP after using cursors.
You can literaly watch it drop in taskman.
FUNCTION ReduceMemory()
Declare Integer SetProcessWorkingSetSize In kernel32 As SetProcessWorkingSetSize ;
Integer hProcess , ;
Integer dwMinimumWorkingSetSize , ;
Integer dwMaximumWorkingSetSize
Declare Integer GetCurrentProcess In kernel32 As GetCurrentProcess
nProc = GetCurrentProcess()
bb = SetProcessWorkingSetSize(nProc,-1,-1)
Yeah I do this with a few of my .NET applications. In fact I hook it up to deactivation of the application. While running leave all the memory it can take, then when you tab off clear out unused memory. It works, but it can be very superficial - usually when you re-activate the app the memory comes right back.
FWIW, Windows will eventually reclaim memory that's not used. For VFP apps and especially apps that use large cursors, running SetProcessWorkingSet
is probably not a good idea as you're effectively killing any cached data that VFP puts into memory and now has to reload.
+++ Rick ---