Jump to content

John Terwiske

Members
  • Content Count

    24
  • Joined

  • Last visited

Posts posted by John Terwiske


  1. 3 minutes ago, Brandon Staggs said:

    This comes up every once in a while here. The short of it is, if you don't subscribe for support, you won't get support once your initial support period expires. That includes being able to download non-public-facing files like ISOs. Thankfully you can download the ISOs after your purchase and keep backups, and those will continue to work, until you hit a registration limit, in which case you need to contact sales and request a bump. (Not support -- if you choose to discontinue your support subscription, you won't get, well, support.)

    When did they tell us we needed iso files?

     

    And now I vent (haha):

    I've always been able to download old versions, install, activate license, etc.  Even without a subscription.  In fact when subscriptions were first instituted developers specifically asked if this subscriptions were going to be required for reinstalls, and the answer was definitely not "you'll always need a subscription to download old versions"

     

    I've sent an email to support, we'll see what they say.

     

     


  2. So I went to reinstall an old licensed version of Delphi 10.3.2.  

    In days gone by it was always possible to download the old installers.

     

    Now I get the following (see photo). 

     

    Is this still possible?  It's been years since I've had to do this.  I have no intention of purchasing an update subscription for a simple reinstall.

     

    Thanks,

    John 

    image_2024-01-17_120417500.png


  3. 2 hours ago, Stefan Glienke said:

    Which PrimeSieve implementation do you use? There has been quite a fuss around that last year after the Youtube Video series by Dave Plummer.

    In the table above, the cpp implementation is the accepted solution for the Dave Plummer YouTube series (Microsoft VS C++ 20 with all optimizations).  The Delphi solution (10.3.3) is the accepted solution for Delphi-- with a couple of modifications that add add about 20% to number of iterations (just by inlining member functions, iirc).

     

    I'm not really surprised by these results, and memory bound apps (my own included) seem to suffer quite a bit with Delphi.  What was the fuss about (not that I wish to reopen a topic)?

     

     

     


  4. If one starts with good algorithm then the only thing that works for me is to do profiling (without instrumentation).  I've had good luck with (the free) Vtune Profiler from Intel.


    Attached is a picture showing comparison of Delphi and Cpp for prime sieving console application on Windows.  This sample uses the Fastmm5, but the differences in cache misses are not that different than the Delphi shipping version of Fastmm.

     

    I should also note that the Delphi implementation needs more work (in the algorithm more than anything else), but this might give you an idea of where to look for performance improvement.  Also, one needs to jump through some hoops to find the actual line in Delphi code where bottlenecks appear (unlike some of the profilers mentioned above which can zero in to function).

     

    image_2022-01-17_120513.png


  5.  

    There are now 48 talks on YouTube from this past October's conference.

     

    I was looking forward to seeing this one, and it didn't disappoint.  The real takeaway for me was that the code we write is not necessarily what the cpu actually does.  Something that I've know for a while, but this presentation really hammers it home from a knowledgeable expert.  There's a lot here for we Delphi users, too.  

    • Thanks 1

  6. I've always enjoyed Herb's talks.  The one that sticks in my mind is where he discusses the possible simplification of parameter passing in C++.  This has (and is) one of the chief complexities of the language that sometimes confounds beginners.  That proposal went no where as far as I can tell, and I don't know exactly why it failed but I think the old canard "it's not C++" or maybe something to do with library compatibility.  Too bad, really.

     

    The other thing about "modern" C++ is that it is very difficult to teach.  There's another talk I think from 2019 at cppcon (Nicholas J., irrc) that discusses the 18 (or more) different ways to initialize an integer.  And once you get into move semantics, compile-time programming, and when and if constexpr works like you think it does then you really need great teaching skills.

     

    Their three year cycle for language enhancements is astonishing.  I remain envious of compilers that can optimize like theirs can.  If only Delphi had...


  7. Do any of the Delphi compilers that use LLVM (do they all use LLVM now?) allow one to output the LLVM Intermediate representation (IR) to a file?  In the Clang / LLVM compilation pipeline this file would typically have an ll extension and is a kid of pseudo-assembly.

     

    Thanks

    • Like 1

  8. 21 hours ago, Koru said:

    In 10.4.1 and 10.2 update 3, it executes ok

    Odd that there would be a regression in 10.3.3.  I'm looking forward to 10.4.1, most especially for the ability to non-statically link to SQLite library.


  9. 14 hours ago, emailx45 said:

    fail... interesting.. using this syxtax works too!

      caption:= GetEnumName(TypeInfo(TFieldType), ord(FDQuery1.FieldByName('ID+''''').DataType));  // = LongInt

    Thanks for the confirmation in 10.3.3. 


  10. In Delphi Rio 10.3.3 (I've not tested this on other versions) there seems to be a parsing bug with this recursive CTE:

    WITH RECURSIVE example1_cte (Id, No, ParsedText, Unparsed) AS
    (
      SELECT Id,    
             0 as No, 
             '' as ParsedText,
             TextToParse || ',' as TextToParseWithTrailingComma 
        FROM test1
        
      UNION ALL       -- "ALL" is not strictly necessary in this example
        SELECT Id,    
               No+1,  -- increment the counter for this row
               SUBSTR(Unparsed, 0, INSTR(Unparsed, ',') ),
               SUBSTR(Unparsed, INSTR(Unparsed, ',') + 1) 
          FROM example1_cte
          WHERE Unparsed <> ''  
    )
        -- SELECT from the recursive cte
      SELECT Id, No, TRIM(ParsedText) as ParsedText
        FROM example1_cte
        WHERE ParsedText <> ''
        ORDER BY Id ASC, No ASC;

    When executed a Firedac error message appears: [FireDac][Phys][SQLite] Error: no such table column: example1_cte.Id.

     

    And yet, if the line below the UNION ALL is changed to SELECT Id+0,  (I.e. just adding a zero to Id), the error message goes away, and the CTE works correctly.

     

    btw, this query works fine without the "+0" in other SQLite query processors (SQLiteStudio).

     

    I think this is a bug, but cannot locate it in JIRA.

     

    Attached is a quick and dirty example project.  (Change the FDQuery1 to remove the "+0" to see the error.)

     

    I don't have 10.4 so not sure this still exists.

    image.png

    Project1.dpr

    Project1.dproj

    Unit1.dfm

    Unit1.pas


  11. 2 hours ago, Anders Melander said:

     

    Something like this:

    
    var
      ZipFile: TZipFile;
      SourceStream: TStream
      TargetStream: TStream;
      LocalHeader: TZipHeader
    begin
      ...
      TargetStream := TMemoryStream.Create;
      try
        ZipFile.Read('foobar.dat', SourceStream, LocalHeader);
        try
          TargetStream.CopyFrom(SourceStream, 0);
        finally
          SourceStream.Free;
        end;
        ...do something with TargetStream...
      finally
        TargetStream.Free;
      end;
    end;

     

    There used to be a problem with unicode in comments but I believe that has been fixed.

    Thank you.  It would appear that whatever issue I was having with unicode is no longer a problem with the Delphi zip code/classes.  Your solution works with all of the non-spanning zip files I've got on hand for testing.  It's about 6% slower vs. the third party solution I'm currently using, and this matters with these files that are in the 2Gbyte range.  I'll look into this some more... someday.  🙂


  12. 56 minutes ago, Anders Melander said:

    Yes, but I don't see how this extracts a single file to a stream of some sort.  And extracting to a file on disk makes these useless for my purposes.  It's almost there, but I think this is why I started using the third party years ago.  Well, that and at the time as I recall there was a problem with unicode characters in the items within the zip file (memory fades on this though.)   


  13. What if there are multiple files within the Zip archive?  I need to extract a specific item within a Zip file.  I'm using a third party component that works like this (streamlined version):

     

    (n.b.  MyUnArchiver is a third party zip component on a Delphi Form)
      
    MyUnArchiver.FileName := 'D:\testdata\largefile.zip';  // the zip file on disk
    
    MyUnzippedStream := TStringStream.Create;  // I use StringStream for processing, but any stream works here
    try
      MyUnArchiver.OpenArchive; 
      MyUnArchiver.ExtractToStream('archive item name', MyUnzippedStream);  // name of the given archive item within the zip file
      MyUnZippedStream.Position := 0;  // the extraction will set the position to end of stream, so this is necessary
    // process MyUnZippedStream
    ..
    finally
      MyUnzippedStream.Free;
    end;


      I'd like to reduce my third party dependencies, but it's a "maybe later" priority.  The third party component (and I am not affiliated with them) is called ZipForge.

     

     


  14. For me, right now, git is it.  However, for really big teams and for those that must still support older versions (remember when that was a thing?) Clearcase worked the best (about 200 developers back then, mostly C, some C++, some Delphi) supporting multiple versions and all of it tied in to bugs and design.  The one I didn't much care for was Continuus, but that was mostly the user interface (the idea was great though.)  I never used Starteam from Borland, but I know folks who did and liked it.


  15. 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.

     

     

     

     

     

     

     

     

    fastmm5MemMan.JPG

    delphidefaultMemMan.JPG


  16. 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.


  17. 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).  


  18. 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.

×