Jump to content

Mike Torrettinni

Members
  • Content Count

    1160
  • Joined

  • Last visited

  • Days Won

    1

Mike Torrettinni last won the day on July 17 2020

Mike Torrettinni had the most liked content!

Community Reputation

124 Excellent

About Mike Torrettinni

Technical Information

  • Delphi-Version
    Delphi 10.2 Tokyo

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Mike Torrettinni

    List of usable RegEx for source code

    I got another one, although this one is probably useful for small number of developers who prefer begin and end in their own lines: ((if)|(while)|(for)).*\sbegin This finds all lines where begin is in the same line as if/for/while statements. I prefer: if condition then begin ... ... end; and not the 'advanced/pro' way: if condition then begin ... ... end; For me, easy readable is preferred over reducing 1 line of code.
  2. Mike Torrettinni

    RegEx performance

    Thanks! The website kind of proves my point why I'm removing all (most) regex. Funny how comments show so many feel so strongly about email regex 😉 Yes, this annoys me too, especially websites requesting email for just basic info. My projects are not like website, so validation is only for typos. It's part of licensing form, so no problem with understanding the purpose.
  3. Mike Torrettinni

    RegEx performance

    Seems like the only RegEx left in my apps will be for email validation. But this is called only once on user entry, so no performance needed. The rest of RegEx will probably phase out slowly.
  4. Mike Torrettinni

    RegEx performance

    Thanks! It doesn't make sense to use RegEx for such example, right? OK, I see it's usable for a few calls, but for anything that searches lost of data, is pretty slow.
  5. I have an old example of RegEx usage and noticed with one customer becomes a bottleneck. So, I did some benchmarking and it was very slow because I create RegEx expressions on each call. So, I optimized it to only create RegEx when is needed. I also took a chance to see if I can get rid of RegEx and using Pos and string iteration is faster of course. The purpose of RegEx is to find if Function() exists in string. The problem is that sometimes there are spaces before bracket, like Function (). The most I found was 4 spaces before I implemented RegEx to replace If 'Function(' or 'Function (' or 'Function (' or 'Function (' is in string, with RegEx: '\b' + vFunc + '[ ]*\(' So, I'm happy to get rid of RegEx for this example. But still wanted to show the code, perhaps I'm using RegEx the wrong way and someone has a suggestion. Here are the timings (ms): 32bit: In 64bit optimized RegEx is a little faster: And code: program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.RegularExpressions, System.Diagnostics; const cNoHit: string = 'Testing string just for testing and more testing.'; cShort: string = 'FunctionA(x)'; cMedium: string = 'Testing FunctionA (1) or Writeln(FunctionB (1+1)) and Not FunctionC( FunctionD(y))'; cLong: string = 'Lorem ipsum dolor FunctionA(a)sit amet, consectetur adipiscing FunctionB(FunctionC (2)) elit. Ut enim neque, dictum vel sodales molestie, FunctionD (10)pretium in neque. Quisque FunctionA (10)rhoncus. Alma e alma de penatibus et FunctionA(99)'; cLoop: integer = 100000; cFunctions: array[1..5] of string = ('FunctionA', 'FunctionB', 'FunctionC', 'FunctionD', 'FunctionN'); // FunctionN is not in test cases function IsFunctionInString_RegEx(const aFunction, aStr: string): boolean; var vRegEx: TRegEx; begin // aFunction can have none or multple spaces between bracket // aFunction(), aFunction (), aFunction ()... vRegEx.Create('\b' + aFunction + '[ ]*\('); Result := vRegEx.IsMatch(aStr); end; function IsFunctionInString_RegEx_Optimized(const aRegEx: TRegEx; const aFunction, aStr: string): boolean; begin // Optimized: aRegEx compiled only once Result := aRegEx.IsMatch(aStr); end; function IsFunctionInString(const aFunction, aStr: string): boolean; var vPos, i: Integer; begin // aFunction can have none or multple spaces between bracket // aFunction(), aFunction (), aFunction ()... // 1. Find aFunction and check if next character is '(', skipping any spaces vPos := Pos(aFunction, aStr); if vPos = 0 then Exit(false); for i := vPos + aFunction.Length to aStr.Length do begin if aStr[i] = '(' then Exit(True); if aStr[i] <> ' ' then Exit(false); end; end; procedure Test_RegEx(const aStr: string); var vSW: TStopWatch; s, vFunc: string; b: boolean; i: Integer; begin vSW := TStopWatch.StartNew; for vFunc in cFunctions do for i := 1 to cLoop do b := IsFunctionInString_RegEx(vFunc, cNoHit); Writeln(' RegEx: ' + vSW.ElapsedMilliseconds.ToString); end; procedure Test_RegEx_Optimized(const aStr: string); var vSW: TStopWatch; s, vFunc: string; b: boolean; i: Integer; vRegEx: TRegEx; begin vSW := TStopWatch.StartNew; for vFunc in cFunctions do begin vRegEx.Create('\b' + vFunc + '[ ]*\('); for i := 1 to cLoop do b := IsFunctionInString_RegEx_Optimized(vRegEx, vFunc, cNoHit); end; Writeln(' RegEx Optimized: ' + vSW.ElapsedMilliseconds.ToString); end; procedure Test(const aStr: string); var vSW: TStopWatch; s, vFunc: string; b: boolean; i: Integer; begin vSW := TStopWatch.StartNew; for i := 1 to cLoop do for vFunc in cFunctions do b := IsFunctionInString(vFunc, cNoHit); Writeln(' Pos: ' + vSW.ElapsedMilliseconds.ToString); end; procedure Validate; var vStrings: array of string; s, vFunc: string; vRegEx: TRegEx; begin vStrings := [cNoHit, cShort, cMedium, cLong]; for s in vStrings do for vFunc in cFunctions do begin vRegEx.Create('\b' + vFunc + '[ ]*\('); if (IsFunctionInString(vFunc, s) <> IsFunctionInString_RegEx(vFunc, s)) or (IsFunctionInString(vFunc, s) <> IsFunctionInString_RegEx_Optimized(vRegEx, vFunc, s)) then raise Exception.Create('Error validating: ' + vFunc + ' in ' + s); end; end; begin Validate; Writeln('No hit str:'); Test_RegEx(cNoHit); Test_RegEx_Optimized(cNoHit); Test(cNoHit); Writeln(''); Writeln('Short str:'); Test_RegEx(cShort); Test_RegEx_Optimized(cShort); Test(cShort); Writeln(''); Writeln('Medium str:'); Test_RegEx(cMedium); Test_RegEx_Optimized(cMedium); Test(cMedium); Writeln(''); Writeln('Long str:'); Test_RegEx(cLong); Test_RegEx_Optimized(cLong); Test(cLong); Writeln(''); Writeln('done...'); Readln; end.
  6. Mike Torrettinni

    List of usable RegEx for source code

    OK, the expressions can become quite hard to manage, so I can see why people are not really that enthusiastic about regex, but here is now my complete list: SetLength\s*\(.*Length\(.*\)\s*\+\s*1 -> SetLength(arr, Length(arr) + 1) SetLength\s*\(.*High\s*\(.*\)\s*\+\s*1 -> SetLength(arr, High(arr) + 1) 0\s*to\s*.*Count\s*do -> 0 to List.Count do 0\s*to\s*.*Length\s*\(.*\)\s*do -> 0 to Length(arr) do raise Exception\( -> raise Exception() (missing .Create like in raise Exception.Create) Exception\.Create\( -> Exception.Create( (verify that Raise is in front ) Full exp: (SetLength\s*\(.*Length\(.*\)\s*\+\s*1)|(SetLength\s*\(.*High\s*\(.*\)\s*\+\s*1)|(0\s*to\s*.*Count\s*do)|(0\s*to\s*.*Length\s*\(.*\)\s*do)|(raise Exception\()|(Exception\.Create\() And of course Delphi's IDE is special and requires a little subtle changes: Delphi IDE: SetLength\s*\(.*Length\(.*\)\s*.*\+\s*.*1 SetLength\s*\(.*High\s*\(.*\)\s*.*\+\s*.*1 0\s*.*to\s*.*.*Count\s*.*do 0\s*.*to\s*.*Length\s*\(.*\)\s*.*do Full exp: (SetLength\s*\(.*Length\(.*\)\s*.*\+\s*.*1)|(SetLength\s*\(.*High\s*\(.*\)\s*.*\+\s*.*1)|(0\s*.*to\s*.*.*Count\s*.*do)|(0\s*.*to\s*.*Length\s*\(.*\)\s*.*do)|(raise Exception\()|(Exception\.Create\()
  7. Mike Torrettinni

    Delphi IDE on AMD cpu?

    Yes, I think I will go for it. Current 32GB was enough, but got close to the max often. So, 64GB should be enough for next 5 years or so.
  8. Mike Torrettinni

    Delphi IDE on AMD cpu?

    Thanks, good to know! Little disappointing with Intel's 11 gen, so looking at AMD. 5900x seems to be a good choice, anything above is overkill for my work.
  9. Mike Torrettinni

    Delphi IDE on AMD cpu?

    Thanks. I agree about the hardware stuff, If you are a developer and someone has to suggest SSD and good cooling, you are wasting time and money on a PC of your choosing, unless someone who knows about this stuff helps you. That's probably not going to be enough for running VMs. Not sure which cpu I will choose, but out of all the software I use, I'm concerned most about Delphi IDE.
  10. Mike Torrettinni

    Delphi IDE on AMD cpu?

    Thanks, good to hear! Do you have Intel in your laptop? A comparable cpu, or 20-30% slower than 5600x? Interesting. Those topics for 10.4.2, on this forum, kind of indicate it could be anything, as consistently inconsistent LSP is working.
  11. Mike Torrettinni

    Delphi IDE on AMD cpu?

    I'm thinking of switching from Intel to AMD. I know the Delphi compiled projects work on AMD cpus, but I worry about Delphi IDE. Especially after 10.4.2 release. Is anybody actively using Delphi IDE on latest AMD cpu 5000 or previous 3000 series, desktop series of course, and can confirm no issues because of AMD cpu?
  12. Mike Torrettinni

    List of usable RegEx for source code

    Is Delphi IDE using some different than normal regex? Why would IDE not work with this expression: to find all SetLength(arr, Length(arr) + 1) FileLocator and regexr.com work with this: SetLength\s*\(.*Length\(.*\)\s*\+\s*1 But for Delphi IDE I need to add .* after some \s* : SetLength\s*\(.*Length\(.*\)\s*.*\+\s*.*1 not found: SetLength\s*\(.*Length\(.*\)\s*\+\s*1 works Ok with extra \s*.*: SetLength\s*\(.*Length\(.*\)\s*.*\+\s*.*1
  13. Mike Torrettinni

    List of usable RegEx for source code

    It would be nice if IDE would allow to search multiple expressions at once, like regex list: search regex(s) = "SetLength.*\(.*Length\(.*\).*\+.*1 "," SetLength.*\(.*High\(.*\).*\+.*1 "," 0 to Length\(.*\).do "," 0 to .*Count[ ]do "," raise e[a-z]*\( " So you can run such check every now and then with simple copy paste of a list. File Locator/Agent Ransack is missing such options, too, shame.
  14. Mike Torrettinni

    List of usable RegEx for source code

    Hm, Ok, I didn't know that. Maybe my original case was a bit different but eventually proved a bottleneck with constant calling Length()+1.
  15. Mike Torrettinni

    List of usable RegEx for source code

    Well, yes, of course. But it can bite you really fast when suddenly you have a customer who has different data and instead of 10K items at 1-10 properties per item (using Length + 1), turns into 10 items with 10K properties each. Then it becomes a bottleneck suddenly.
×