Jump to content

Mike Torrettinni

Members
  • Content Count

    1509
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by Mike Torrettinni

  1. I don't understand, what is missing that would be MCVE? I have description, results and code, what could I include to improve the test case?
  2. I checked my string replacements in more details and on average there are 3 replacements in long strings. So, I included test with 3 replacement and the difference using Pos before StringReplace or without Pos is even smaller, 1% only, while when substring is not found not using Pos adds 100%+ to the execution time. Short string Find + Pos: 1322 Short string Find - Pos: 1275 Short string 3x Find + Pos: 1504 Short string 3x Find - Pos: 1482 Short string NO Find + Pos: 98 Short string NO Find - Pos: 686 Long string Find + Pos: 2525 Long string Find - Pos: 2322 Long string 3x Find + Pos: 2609 Long string 3x Find - Pos: 2517 Long string NO Find + Pos: 660 Long string NO Find - Pos: 1452 So, using Pos before StringReplace saves a lot of time, unless we are sure that the substring exists, then it adds some time, depending on string length. program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Diagnostics; const cMaxLoop = 10000000; cShortStr = 'Testing string magna.'; cShortStr3x = 'Testmag strmaging magna.'; cLongStr = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'; cLongStr3x = 'Lorem ipsum dolor sit ametmag, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequatmag.'; cFind = 'mag'; cNoFind = 'mga'; cReplace = 'X'; var vNewStr: string; vSW: TStopWatch; c: Integer; procedure TestShort_Find; begin vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do if Pos(cFind, cShortStr) > 0 then vNewStr := StringReplace(cShortStr, cFind, cReplace, [rfReplaceAll]); Writeln('Short string Find + Pos: ' + vSW.ElapsedMilliseconds.ToString); vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do vNewStr := StringReplace(cShortStr, cFind, cReplace, [rfReplaceAll]); Writeln('Short string Find - Pos: ' + vSW.ElapsedMilliseconds.ToString); end; procedure TestShort_NoFind; begin vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do if Pos(cNoFind, cShortStr) > 0 then vNewStr := StringReplace(cShortStr, cNoFind, cReplace, [rfReplaceAll]); Writeln('Short string NO Find + Pos: ' + vSW.ElapsedMilliseconds.ToString); vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do vNewStr := StringReplace(cShortStr, cNoFind, cReplace, [rfReplaceAll]); Writeln('Short string NO Find - Pos: ' + vSW.ElapsedMilliseconds.ToString); end; procedure TestShort_Find3x; begin vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do if Pos(cFind, cShortStr3x) > 0 then vNewStr := StringReplace(cShortStr3x, cFind, cReplace, [rfReplaceAll]); Writeln('Short string 3x Find + Pos: ' + vSW.ElapsedMilliseconds.ToString); vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do vNewStr := StringReplace(cShortStr3x, cFind, cReplace, [rfReplaceAll]); Writeln('Short string 3x Find - Pos: ' + vSW.ElapsedMilliseconds.ToString); end; procedure TestLong_Find; begin vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do if Pos(cFind, cLongStr) > 0 then vNewStr := StringReplace(cLongStr, cFind, cReplace, [rfReplaceAll]); Writeln('Long string Find + Pos: ' + vSW.ElapsedMilliseconds.ToString); vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do vNewStr := StringReplace(cLongStr, cFind, cReplace, [rfReplaceAll]); Writeln('Long string Find - Pos: ' + vSW.ElapsedMilliseconds.ToString); end; procedure TestLong_NoFind; begin vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do if Pos(cNoFind, cLongStr) > 0 then vNewStr := StringReplace(cLongStr, cNoFind, cReplace, [rfReplaceAll]); Writeln('Long string NO Find + Pos: ' + vSW.ElapsedMilliseconds.ToString); vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do vNewStr := StringReplace(cLongStr, cNoFind, cReplace, [rfReplaceAll]); Writeln('Long string NO Find - Pos: ' + vSW.ElapsedMilliseconds.ToString); end; procedure TestLong_Find3x; begin vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do if Pos(cFind, cLongStr3x) > 0 then vNewStr := StringReplace(cLongStr3x, cFind, cReplace, [rfReplaceAll]); Writeln('Long string 3x Find + Pos: ' + vSW.ElapsedMilliseconds.ToString); vSW := TStopWatch.StartNew; for c := 1 to cMaxLoop do vNewStr := StringReplace(cLongStr3x, cFind, cReplace, [rfReplaceAll]); Writeln('Long string 3x Find - Pos: ' + vSW.ElapsedMilliseconds.ToString); end; begin TestShort_Find; TestShort_Find3x; TestShort_NoFind; TestLong_Find; TestLong_Find3x; TestLong_NoFind; Readln; end.
  3. Yes, I put it on ToDo list to revisit - 5 years ago when I tried to implement it it was 10x slower than normal StringReplace call, perhaps because they way I was concatenation strings. Now I can probably improve it, I just need to book the time. Good thing is nobody is disputing that Pos is good improvement to use with StringReplace, when we don't know if call is actually needed or not - if sub string is in the string. Of course for repetitive calls, like in my case.
  4. I tried to customize the StringReplace to use Pos and exit asap if string is not found within, but I broke something for other cases, so I had to give up 🙂
  5. I used similar code for replacing strings in pre 2009, but at that time the performance was not my main focus. I guess I should have started at that time and perhaps I wouldn't deal with this now 😉
  6. You are talking about pre 2009 versions?
  7. Yes, I wasn't successful in creating final version of multiple string replace function in one go.
  8. Based on my Delphi knowledge this would probably be way more expensive (in hours, days), and highly likely it will not result in 'faster in all cases'.
  9. Yes, of course. Currently working on this part of the code that is a bottleneck. Want to make sure it doesn't regress, so every step is measured and evaluated. The fact is that only a few customers have data that this code is needed. So, it's a tradeoff between slower by 5% for 5% cases and 50-80% faster for 95% cases.
  10. I guess Pos before StringReplace is already an improvement, when substring is not found but we don't know it.
  11. Just did the search through my code and I only use Pos when dealing with a lot of data, when there is repetitive call to StringReplace. Otherwise not, since the performance is not important. Any recommendations on more efficient function?
  12. Aha, I just noticed StrigReplace has rfIgnoreCase flag.
  13. Yes, it doesn't use Pos to check if it needs replacing at all. Which is strange. But that is in Delphi 10.2.3, perhaps newer version has this fixed. Which version of Delphi do you use, does it have Pos check at the beginning?
  14. Is anybody customizing source editor? I usually just change font, right now using Source code pro, but just realized I can make comments non-italic and solve the years long annoyance with cut of last char 😉 Any other suggestions on small changes that can improve the source editor?
  15. Ok, this makes sense now. So in terms on warnings: they count number of reported lines since 1 warning is reported on 2 lines. Perhaps a rewording of what is reported on Compile window would be useful.
  16. I think we understood original post differently. He reported, questioned how errors are counted. I found similar issue in counting Warnings. Hints look to be OK. If reporting on these numbers is not useful, why is it there then?
  17. Well, nobody is suggesting joining the class action suit against Embarcadero for not counting correctly, is just counting, right? How could they mess this up?
  18. You are pretty vague here... big picture of what, what are you talking about?
  19. You don't read blogs? I like to, usually is condensed topic vs books.
  20. Since I prefer short blogs over books, I suggest googling: " is attention to detail useful?" and you will find many blogs and even books that might be helpful to you, in software development and also in life.
  21. You don't think it should report 1 Warnings if there is only1 Warning? Why it counts the same warning 2 times? Hints work correct, 1 Hint = 1 reported Hint.
  22. Looks like Warnings is off by 1 too - well it counts same Warning 2x: @c0d3r I guess you started the scrutiny of Compile window... looks even more broken, unfortunately I'm using Delphi 10.2.3, I hope newer versions have this improved.
  23. It's the same result in 10.2.3, not sure which version you have. I guess Delphi has it's own broken windows theory 😉
  24. Just interested how others view this implementation: processOrder(dontUseWidget: Boolean) { if not dontUseWidget then { processOrderWithWidget(); } else { processOrderWithoutWidget(); } } Nick Hodges describes here: https://medium.com/nickonsoftware/twenty-one-ways-to-be-a-crappy-software-developer-c69e4b39c5df- see #20 Use boolean parameters to make your functions do two things I use such code similar as abode, or in examples like: procedure EnableDisableControls(aEnabled: boolean = True); begin MainForm.Control.Enabled := aEnabled; ... end; and a few other instances. I'm just curious how others see this example, is anybody else using it or is it really that bad example that it should be nuked out of any project?
  25. Oh, maybe this should be for Google Translate.
×