John Terwiske 4 Posted July 26, 2020 Hello, I'm a bit confused about my code with regard to FastMM5. FastMM5 appears to be 15 percent slower than the regular in-built (FastMM?) memory manager that comes with Delphi 10.3.3. This matters, as I need to process thousands of these files, and it's been years since I've worked with Delphi. Hopefully, there's something I'm forgetting to do, and folks here can help. Here's the code: procedure TForm1.Button2Click(Sender: TObject); var StreamToReadFrom: TStreamReader; LineCounter: Integer; MyString: string; MyUnzippedStream: TBufferedFileStream; //TReadOnlyCachedFileStream<== faster than TBufferedFileStream, but still slower under FastMM5; MyStopwatch: TStopWatch; begin Memo1.Clear; LineCounter := 0; MyStopwatch := TStopwatch.Create; MyStopwatch.Start; // The file D:\variants.vcf is approximately 48.4 million bytes with 202K varying length lines of text that is not unicode MyUnZippedStream := TBufferedFileStream.Create('D:\variants.vcf', fmOpenRead); try StreamToReadFrom := TStreamReader.Create(MyUnZippedStream, False); try StreamToReadFrom.Rewind; while not StreamToReadFrom.EndOfStream do begin MyString := StreamToReadFrom.ReadLine; if AnsiStartsStr( '#C', MyString ) then Memo1.Lines.Add( MyString ); Inc(LineCounter); end; finally StreamToReadFrom.Free; end; finally MyUnZippedStream.Free; MyStopwatch.Stop; end; Memo1.Lines.Add( 'Lines read: ' + LineCounter.ToString ); Memo1.Lines.Add( 'Milliseconds: ' + mystopwatch.ElapsedMilliseconds.ToString ); end; This code is a highly simplified portion of a stage used in a complicated pipeline. This is fairly fast as it is in just one thread, but a 15% slowdown under FastMM5 for thousands of these files is not really something I was looking to see. Share this post Link to post
Dave Novo 51 Posted July 27, 2020 Is it possible you are running FastMM5 with memory leak tracking on, in debug mode? That will be much slower than the one that ships with Delphi, as it is tracking all memory allocations and de-allocations for memory leak reporting purposes, bad memory overwrites etc. Share this post Link to post
Fr0sT.Brutal 900 Posted July 27, 2020 The experiment isn't clean. You have whole process of reading from HDD included which is very variable because of OS file cache mechanism. You also add search action that is not relevant to memory allocations. Share this post Link to post
Arnaud Bouchez 407 Posted July 27, 2020 FastMM5 purpose is to shine with multi-threaded apps. For a single-threaded app, e.g. a simple RAD VCL/FMX project, performance may not be really better. Note: your benchmark function will probably spend most of its time not within the MM. I guess most of the time is spent in Memo1.Lines.Add if the search string occurs often. Share this post Link to post
John Terwiske 4 Posted July 27, 2020 4 hours ago, Arnaud Bouchez said: FastMM5 purpose is to shine with multi-threaded apps. For a single-threaded app, e.g. a simple RAD VCL/FMX project, performance may not be really better. Note: your benchmark function will probably spend most of its time not within the MM. I guess most of the time is spent in Memo1.Lines.Add if the search string occurs often. Yes, I'm working to incorporate this "reading" stage into a pipeline using a threaded approach with OmniThreadLibrary. That's why I'm looking at FastMM5. I suppose I'll need to create a test that launches several "readers" for a few hundred of these files to see improvement with FastMM5. My shortcut of just trying one file is not sufficient for testing that.. darn it. (Btw, the search string only occurs once in the file, Memo1.Lines.Add just happens once. The vcf file format is well defined in the genetic analysis domain; this "#C" is the a way of identifying column headings/field names used for the remainder of the file). Share this post Link to post
John Terwiske 4 Posted July 27, 2020 8 hours ago, Dave Novo said: Is it possible you are running FastMM5 with memory leak tracking on, in debug mode? That will be much slower than the one that ships with Delphi, as it is tracking all memory allocations and de-allocations for memory leak reporting purposes, bad memory overwrites etc. I checked and no. However, your idea reminded me that FastMM_SetOptimizationStrategy(mmosOptimizeForSpeed) is there as an option. I'm reworking my test launch a threaded version that will work with a few hundred of these files and I'll compare FastMM5 and the Delphi memory manager. Share this post Link to post
John Terwiske 4 Posted July 27, 2020 5 hours ago, Fr0sT.Brutal said: The experiment isn't clean. You have whole process of reading from HDD included which is very variable because of OS file cache mechanism. You also add search action that is not relevant to memory allocations. Yes, all true. Share this post Link to post
John Terwiske 4 Posted July 28, 2020 Here are some results comparing the Delphi built-in memory manager and the one from FastMM5. Please see my earlier post in this thread. Indeed, the performance is much improved with multi-threading under FastMM5 vs. the in-built Delphi MM. Although a non-threaded single pass comparison was more favorable to the built-in memory manager for 10.3.3, the more real-world testing is significantly more favorable to FastMM5. This simple test consists of reading 50 of the vcf files I mentioned in my earlier post. Each of them is about 48 Mb and uses a threaded approach with 12 physical cores on the test machine, together with the OmniThreadLibrary Parallel.ForEach paradigm. These times are for the 64 bit executable (slightly faster with 32 bit exe, as expected) Delphi 10.3.3 built-in Memory Manager: 21929 milliseconds FastMM5: 4762 ms For FastMM5, there is an approximate 1.5% decrease in time taken using the OptimizeForSpeed strategy. Share this post Link to post