Jump to content

Mike Torrettinni

Members
  • Content Count

    1509
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by Mike Torrettinni


  1. I have a few functions where I check if 'data' is 'a control', and in some cases I use MatchStr where I have string info, and IN where I have integer ID:

    function IsControlGroupA(const aControl: string): boolean;
      Result := MatchStr(aControl, ['Edit', 'Check', 'ComboBox', 'RadioBtn', 'ListBox']);
    end;
    
    function IsControlGroupX(aControl: integer): boolean;
      Result := aControl in [xConttrols.EditID, xConttrols.CheckID, xConttrols.ComboBoxID, xConttrols.RadioBtnID, xConttrols.ListBoxID];
    end;
    

    Replacing MatchStr with OR is of course much faster - because we know MatchStr is quite inefficient compared to simple = comparison, so this is much faster:

    function IsControlGroupA(const aControl: string): boolean;
      Result := (aControl = 'Edit') or (aControl = 'Check') or (aControl = 'ComboBox') or (aControl = 'RadioBtn') or (aControl = 'ListBox');
    end;

     

    Then I looked at IN and it looks like simple check of integers, which is fast anyway. So, I benchmarked if it's worth replacing it also with OR:

    function IsControlGroupX(aControl: integer): boolean;
      Result := (aControl = xConttrols.EditID) or (aControl = xConttrols.CheckID) or (aControl = xConttrols.ComboBoxID) or (aControl = xConttrols.RadioBtnID) or (aControl = xConttrols.ListBoxID);
    end;

     

    Then I remember reading Marco's response on Case vs If Else about a single comparison and jump:

    https://twitter.com/marcocantu/status/1501844578898530308?cxt=HHwWiMC-kf_rz9cpAAAA

     

    so I put Case into benchmarking and seems like Case is not suitable for my data, since I don't use a large number of ordinals, like Marco explained when Case is faster, and I don't use If Else, so probably not good case anyway, but I put it in so I know how it go against OR.

     

    In test benchmark, the OR is a winner, and Case is a bit slower especially in 64bit - which I'm slowly moving into anyway:

    I benchmarked with my current D 10.2.3 and D 11.1 running in VM:

     

    image.png.a1bd2e5fe23136fae0e0cfff5d39fc44.png

     

    As Marco said, perhaps if I had a large number of checks and if I compared it to If Else, it could win.

     

     

    The real-life difference in one data sample, the most used check for a group is 6x faster using OR vs IN:

     

    using IN:      image.png.8a6e84c89e2f50fa5edc927c3b9f5b1f.png

    using OR:     image.png.81aa39851a4ad3c87568724cc6b74347.png

     

    So, definitely quite useful improvement!

     

     

    1 fact about Case: as we know you can't use Case on non-constant expressions, so using Case for my functions would require a good amount of code change. If it proved to be significantly faster then OR, I would make the change, but it's not.

     

     

    As usual I'm just looking for comment on my observations, perhaps suggestion on something I don't see or didn't take into consideration.

     

    And the benchmark code - with the usual limitation of simple repeated calls:

     

    program Project1;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils,
      System.Diagnostics;
    
    type
      TControlsRec = record
        EditID, ButtonID, CheckID, FormID, FrameID, ListBoxID, PageControlID, TabControlID, RadioBtnID, ComboBoxID: integer;
        EditStr, ButtonStr, CheckStr, FormStr, FrameStr, ListBoxStr, PageControlStr, TabControlStr, RadioBtnStr, ComboBoxStr: string;
      end;
    
    var
      xControlsRec: TControlsRec;
    
    procedure AssignControlsRec;
    begin
      xControlsRec.EditID        := 1; xControlsRec.EditStr        := 'Edit';
      xControlsRec.ButtonID      := 2; xControlsRec.ButtonStr      := 'Button';
      xControlsRec.CheckID       := 3; xControlsRec.CheckStr       := 'Check';
      xControlsRec.FormID        := 4; xControlsRec.FormStr        := 'Form';
      xControlsRec.FrameID       := 5; xControlsRec.FrameStr       := 'Frame';
      xControlsRec.ListBoxID     := 6; xControlsRec.ListBoxStr     := 'ListBox';
      xControlsRec.PageControlID := 7; xControlsRec.PageControlStr := 'PageControl';
      xControlsRec.TabControlID  := 8; xControlsRec.TabControlStr  := 'TabControl';
      xControlsRec.RadioBtnID    := 9; xControlsRec.RadioBtnStr    := 'RadioBtn';
      xControlsRec.ComboBoxID    := 10; xControlsRec.ComboBoxStr   := 'ComboBox';
    end;
    
    function IsIN(aID: integer): boolean;
    begin
      Result := aID in [xControlsRec.ButtonID,  xControlsRec.FormID, xControlsRec.ListBoxID, xControlsRec.TabControlID, xControlsRec.ComboBoxID];
    end;
    
    function IsOR(aID: integer): boolean;
    begin
      Result := (aID = xControlsRec.ButtonID) or (aID = xControlsRec.FormID) or (aID = xControlsRec.ListBoxID) or (aID = xControlsRec.TabControlID) or (aID = xControlsRec.ComboBoxID);
    end;
    
    function IsCase(aID: integer): boolean;
    begin
      case aID of
        2,4,6,8,10: Result := True;
        else
          Result := false;
      end;
    end;
    
    function IsCase2(aID: integer): boolean;
    begin
      case aID of
        2: Result := True;
        4: Result := True;
        6: Result := True;
        8: Result := True;
        10: Result := True;
        else
          Result := false;
      end;
    end;
    
    
    const
      cLoop = 100000000;
    
      // Values/ControlIDs to search for
      // 3 values are in the group, 2 are not - similar ratio as in real data
      cSearch: array[1..5] of integer = (2,4,5,8,11);
    
    var vSW: TStopwatch;
        vBool:boolean;
        i: integer;
    begin
      AssignControlsRec;
    
      // IsIN
      vSW := TStopwatch.StartNew;
      for i := 1 to cLoop do
      begin
        vBool := IsIN(cSearch[1]);
        vBool := IsIN(cSearch[2]);
        vBool := IsIN(cSearch[3]);
        vBool := IsIN(cSearch[4]);
        vBool := IsIN(cSearch[5]);
      end;
      vSW.Stop;
      Writeln(Format('IsIN    = %5s', [vSW.ElapsedMilliseconds.ToString]));
    
      // IsOR
      vSW := TStopwatch.StartNew;
      for i := 1 to cLoop do
      begin
        vBool := IsOR(cSearch[1]);
        vBool := IsOR(cSearch[2]);
        vBool := IsOR(cSearch[3]);
        vBool := IsOR(cSearch[4]);
        vBool := IsOR(cSearch[5]);
      end;
      vSW.Stop;
      Writeln(Format('IsOR    = %5s', [vSW.ElapsedMilliseconds.ToString]));
    
      // IsCase
      vSW := TStopwatch.StartNew;
      for i := 1 to cLoop do
      begin
        vBool := IsCase(cSearch[1]);
        vBool := IsCase(cSearch[2]);
        vBool := IsCase(cSearch[3]);
        vBool := IsCase(cSearch[4]);
        vBool := IsCase(cSearch[5]);
      end;
      vSW.Stop;
      Writeln(Format('IsCase  = %5s', [vSW.ElapsedMilliseconds.ToString]));
    
      // IsCase2
      vSW := TStopwatch.StartNew;
      for i := 1 to cLoop do
      begin
        vBool := IsCase2(cSearch[1]);
        vBool := IsCase2(cSearch[2]);
        vBool := IsCase2(cSearch[3]);
        vBool := IsCase2(cSearch[4]);
        vBool := IsCase2(cSearch[5]);
      end;
      vSW.Stop;
      Writeln(Format('IsCase2 = %5s', [vSW.ElapsedMilliseconds.ToString]));
    
      readln;
    end.

     

    • Like 1

  2. 4 minutes ago, Fons N said:

    Thanks. Yes, now I can select 64 bit. I don't recall doing that in Delphi 10.4.x though. Or maybe I am getting old and I don't remember that anymore :classic_biggrin:

     

    It's the same for me, some settings you use so rarely it's easy to forget. The reason I know this one is because I'm making my projects ready for 64bit and did a few test installations recently and making sure 64bit is available platform.


  3. 14 minutes ago, Achim Kalwa said:

    Any hints on how to customize the background image on Welcome page?

    Changing the theme in Tools -> Options -> Welcome Page, or loading a custom image, has no effect 😞

     

    It worked for me, I just selected a delphipraxis.png logo file:

     

    image.thumb.png.f1326a45aba5974f00dacf38d30aeb13.png

     

    I don't know who thought that awful bg color looks good.

    • Like 2

  4. Great! Just a little something they still need to do: 

     

     

    [5e9d67bd4958162e561dcaf6] /CodeExamples/Alexandria/en/Main_Page Wikimedia\Rdbms\DBQueryError from line 1457 of /var/www/html/shared/BaseWiki31/includes/libs/rdbms/database/Database.php: A database query error has occurred. Did you forget to run your application's database schema updater after upgrading?
    Query: SELECT lc_value FROM `cde_alexandria_en_l10n_cache` WHERE lc_lang = 'en' AND lc_key = 'deps' LIMIT 1
    Function: LCStoreDB::get
    Error: 1146 Table 'wikidb.cde_alexandria_en_l10n_cache' doesn't exist (10.50.1.120)

     

    • Haha 1

  5. 5 minutes ago, CyberPeter said:

    They really don't care do they ? 

    I assume they would care very much as soon as one (or a few) of the big customers would say to fix it before they pay their yearly fee.

     

    8 minutes ago, CyberPeter said:

    totally ignoring the community and not communication about it at all.

    Eh, no big bucks in community itself.

     

    Probably many of you guys who are part of bigger teams (2 developers and up 🙂 ) can say that rarely the whole team cares about stuff like that.

    100% of my team is not happy about stuff like that is not shy about voicing it. But, my team is just me.

     

    If one of the bigger teams would voice dissatisfaction to their bosses, as a whole team, perhaps they can move some stuff.

    • Like 1

  6. 2 hours ago, Anders Melander said:

    SourceTree is made by Atlassian. Any time you spend reporting bugs to them would better spent picking your nose.

    Yes, I had a feeling it could be something like that. Their SourceTree support site doesn't give too much confidence: https://community.atlassian.com/t5/Sourcetree/ct-p/sourcetree

    Luckily, it was mistake on my side not realizing the option to ignore whitespace was switched on, in Beyopnd Compare, so nothing to report to JIRA.


  7. 1 hour ago, Uwe Raabe said:

    This is probably a project last edited with an older Delphi version, which always wrote two spaces. Alas, I don't remember which one.

    It could be some relic from older versions (the project went from D7 -> D2006 -> D2009 -> a few XEs -> 10.2.3), and I've been using 10.2.3 for years now with this project, and the change I showed above occurred in today's commit.


  8. 1 hour ago, Der schöne Günther said:

    whitespace changes

    That was it! I had an option to hide whitespace difference. Here is without this option enabled:

     

    image.png.b019826486032ea6444c7f9363466dea.png

     

     

    I checked the other .dproj files and with new project and actually double (4 char) indentation seems to be normal, so every now and then I get a version with single (2 char) indentation.

     

     

     


  9. Every now and then I notice that SourceTree seems to detect as if the whole .dproj file is changed:

     

    image.thumb.png.a9e65f601144f066b9a8a37b358d44a5.png

     

    ... and all red lines until line 499, the limit to what it shows. If I use External diff option, the Beyond Compare finds just 2 lines of change:

     

    image.png.52d12f7f09b34710668bf2dfe5a8333a.png

     

     

    I will report to JIRA, but since it's freeware I doubt any useful help will be provided.

     

    I'm curios if anybody else noticed this anomaly and found a solution. Could it be 10.2.3 IDE is causing some odd issue that triggers how SourceTree handles this file, while BeyondCompare handles it correctly?


  10. Actually it seems I could use regex at the end. I managed to find diff between 2 scripts and get results like this:

    Common[0]  = select fname, lname, city, zip, taxcategory, taxowed from taxcustomers where taxcategory = '
    Common[1]  = ' and taxowed>

    then I can define regex like this:

     

    (?<=Common[0]).*?(?=Common[1])

    and will extract all taxcategory values from all scripts, so:

     

    ['TXX-01', 'NL-xxxx' , ... ]

     

    I just need to then extract after Common[1], but I don't have correct regex script, yet.

     

    But using regex gets a lot more complicated with more than 2 Common parts in same script.

     


  11. 10 hours ago, dummzeuch said:

    The person responsible is sitting in Australia, the access to the server is only available during business hours in California and needs the approval from somebody in Europe. And the server does not have a reset button because that would be a security risk. 😉

    If this is the case, this looks more and more like international failure 😉


  12. 18 minutes ago, Brian Evans said:

    A lot  of SQL is executed with parameters which would be a much easier to use form of the data than logs containing SQL with values inline. It also reduces clutter as static values show up as such vs looking the same as a parameter that might change. Where are these logs coming from? Can they be updated to log SQL + parameter value list?  

    They can't control the content of the log. It's some type of an audit log that sometimes contain info on critical accounts, errors... and I offered to provide a viewer that would make sense and be useful to them.

    It depends on date range, but there could be single or multiple log files, each containing from 10s to 1000s of scripts. So, I need to parse and reduce the scripts to manageable and viewable form.


  13. 2 hours ago, Fr0sT.Brutal said:

    I'm afraid what you want couldn't be done exactly via string routines. In the best case you could detect values but you want field names as well. Likely you'd better go SQL parsing way

    I will see how far I get with string diff. Perhaps I was too ambitious about getting each column and it's possible values, and just showing common string part and then list of differences, could be useful enough.

     

    SQL parsing will get me a lot of info, but will be hard to reconstruct the matching script part. Perhaps a combination of both approaches, but this is a lot of testing what will work for useful outcome.

     


  14. At the end it could be just a simple explanation, like with Bookmarks plugin: one of the managers is personally responsible and they would rather have current situation then to explain why someone else could be better suited to sort out the issue and manage in the future.

     

    Probably someone just needs to press reset button on the server.


  15. 14 minutes ago, Der schöne Günther said:

    You are looking for regular expressions. I would like to point you to Delphis documentation, but it has been offline for weeks now. Everything you need is in the unit System.RegularExpressions.

    Why do you suggest regular expression? I don't know what the scripts will be in the log, so I can't use TRegEx.Matches, if that's what you are hinting at. Or am I wrong?

×