Leaderboard
Popular Content
Showing content with the highest reputation on 10/12/20 in all areas
-
Simple inlined function question
David Heffernan replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Well, it's reasonable to wonder about that, and Stefan talked about that. But you actually spent a lot of time talking not about the codegen, but about performance. And the key point is that there is no performance difference for the two versions of the code that you presented, once you put the code in a context where it actually does something. After all, the code you showed doesn't initialise any variables, and just performs the exact same two comparisons on each iteration of the loop. Here's a question for you, why don't you compare the run time of your code, with code where your for loop is removed? I bet it will be faster with the for loop removed. And the code does the same thing with or without the for loop. Obviously that's silly because the for loop is meant to represent some real world code. But it's only meaningful in the context of actual production code. I've said it many times, but when you put your two variants into your real world program, you won't be able to tell them apart from the perspective of performance. -
DEC (Delphi Encryption Compendium) has a new home
Anders Melander replied to TurboMagic's topic in Delphi Third-Party
The first point of entry is the readme. If the readme doesn't convince a potential user then I'm pretty sure they won't bother with the source. We're all busy. Why should you care? Because more users means more people that are likely to contribute. -
An XML DOM with just 8 bytes per node
Erik@Grijjy posted a topic in Tips / Blogs / Tutorials / Videos
Check out some of the interesting algorithms and data structures used to create an extremely light-weight XML DOM. https://blog.grijjy.com/2020/10/07/an-xml-dom-with-just-8-bytes-per-node/ -
DEC (Delphi Encryption Compendium) has a new home
Fr0sT.Brutal replied to TurboMagic's topic in Delphi Third-Party
My own personal logic would be: author doesn't support minimal readme and description => he is very lazy => project will be very poorly maintained => I'll better look for another one. -
Oz-SGL, a new generic collections library based on the idea of C++ STL
David Heffernan replied to Edwin Yip's topic in Algorithms, Data Structures and Class Design
Records can be managed types -
After searching the internet for infos with very little to none success I am still looking for infos about development of AU plug-ins with Delphi/FMX for Mac . Anyone done it successfully and willing to share his/her experience ? Thanks for reading !
-
Simple inlined function question
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Classic measuring issues. I ran the same code in 10.4.1 and while it produces the same asm code the first loop ran slower for me (461 vs 232). I have seen this before and I guess its because the TStopwatch code is not yet in the cache for the first run - same is true for code to be measured. That is why for running good benchmarks you either run both in their own binary and not back to back in the same one - in order for them to be both affected by being a cold run or you simply run the benchmark once to warm up and then start measuring. There are more things to consider though but I won't go into detail here. Edit: compiled in 10.1 the second loop indeed runs slower for me as well. Unit1.pas.46: for i := 1 to loop do 005CE6D2 8B1D54C95D00 mov ebx,[$005dc954] 005CE6D8 85DB test ebx,ebx 005CE6DA 7E1A jle $005ce6f6 Unit1.pas.47: if (vSearchValue = '') and (vItemValue <> '') or (vItemValue = vSearchValue ) 005CE6DC 837DFC00 cmp dword ptr [ebp-$04],$00 005CE6E0 7506 jnz $005ce6e8 005CE6E2 837DF800 cmp dword ptr [ebp-$08],$00 005CE6E6 750B jnz $005ce6f3 005CE6E8 8B45F8 mov eax,[ebp-$08] 005CE6EB 8B55FC mov edx,[ebp-$04] 005CE6EE E8DDC2E3FF call @UStrEqual Unit1.pas.46: for i := 1 to loop do 005CE6F3 4B dec ebx 005CE6F4 75E6 jnz $005ce6dc vs Unit1.pas.53: for i := 1 to loop do 005CE74B 8B1D54C95D00 mov ebx,[$005dc954] 005CE751 85DB test ebx,ebx 005CE753 7E24 jle $005ce779 Unit1.pas.54: if IsSearchByValueFound_Inlined(vSearchValue, vItemValue) 005CE755 837DFC00 cmp dword ptr [ebp-$04],$00 005CE759 7506 jnz $005ce761 005CE75B 837DF800 cmp dword ptr [ebp-$08],$00 005CE75F 7511 jnz $005ce772 005CE761 8B45F8 mov eax,[ebp-$08] 005CE764 8B55FC mov edx,[ebp-$04] 005CE767 E864C2E3FF call @UStrEqual 005CE76C 7404 jz $005ce772 005CE76E 33C0 xor eax,eax 005CE770 EB02 jmp $005ce774 005CE772 B001 mov al,$01 005CE774 84C0 test al,al Unit1.pas.53: for i := 1 to loop do 005CE776 4B dec ebx 005CE777 75DC jnz $005ce755 So there is indeed a difference in the code which affects the performance which goes back to what I said before - the inliner not doing its best job - what you see here is that the compiler still generates that result variable and either sets it to true or to false and then checks that one. But the first loop is only faster because you don't do anything after the check. Edit: One more thing that is important when measuring stuff like this in comparison directly - cache lines. In my case the second loop is always faster in 10.4 even though both of them have the same code generated - and that is simply because the first loop spans two cachelines and the second one in only one - that is something you cannot influence easily and should not bother with but need to be kept in mind when doing measuring code like this. -
Simple inlined function question
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Unfortunately that is true for almost all code in Delphi - and the reason why there are so many "do I better write the code like this or that" discussions - because we constantly have to help the compiler writing code in certain ways when we want to get the optimum. The inliner is not effective as it could be - I would guess the reason being the Delphi compiler is mostly a single pass compiler - so it does not run another optimization step after the inlined code. That means that often there is register or stack juggling happening after the inlining took place that would not have been there if the code would have written there directly. But again: measure and evaluate if it matters. And be careful when measuring it because simply taking both different codes and timing it won't be enough. -
Simple inlined function question
Kryvich replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
@Mike Torrettinni What version of Delphi are you using and what compiler directives are set? I ran your test in Delphi 10.3 CE and I got the same assembler code for both cases. TestStringHelper.dpr.23: if (vSearchValue = '') and (vItemValue <> '') or (vItemValue = vSearchValue ) 004E9AA1 837DFC00 cmp dword ptr [ebp-$04],$00 004E9AA5 7506 jnz $004e9aad 004E9AA7 837DF800 cmp dword ptr [ebp-$08],$00 004E9AAB 750B jnz $004e9ab8 004E9AAD 8B45F8 mov eax,[ebp-$08] 004E9AB0 8B55FC mov edx,[ebp-$04] 004E9AB3 E8301CF2FF call @UStrEqual ... TestStringHelper.dpr.29: if IsSearchByValueFound_Inlined(vSearchValue, vItemValue) 004E9B49 837DFC00 cmp dword ptr [ebp-$04],$00 004E9B4D 7506 jnz $004e9b55 004E9B4F 837DF800 cmp dword ptr [ebp-$08],$00 004E9B53 750B jnz $004e9b60 004E9B55 8B45F8 mov eax,[ebp-$08] 004E9B58 8B55FC mov edx,[ebp-$04] 004E9B5B E8881BF2FF call @UStrEqual -
An XML DOM with just 8 bytes per node
Alexander Elagin replied to Erik@Grijjy's topic in Tips / Blogs / Tutorials / Videos
No, it is not. -
Simple inlined function question
David Heffernan replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
This test seems pointless because the two strings are always empty. You never read the strings from a collection. You never compare two strings. When you put this code into a realistic setting you'll likely find that it makes no difference to performance which versions you use. The smells of premature optimisation. And that results in hard to maintain code. -
I guess you mean whether it is in Light or Dark mode? If so, take a look at GetUserInterfaceStyle, here: https://github.com/DelphiWorlds/Kastri/blob/master/Core/DW.UIHelper.iOS.pas
-
Simple inlined function question
Attila Kovacs replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Register optimization, I never put more than one test into one procedure, but the problem is the inlining introduce the extra boolean evaluation instead of just the 3 in the "if". 🤷♂️ -
Well, if you come to Pasadena, you can visit and see it running beautifully 😀 We have a bank of 5 servers. Each one is 24 cores and 200GB of ram. They each run about 75 headless windows machines each in a citrix environment. We have 4000 visual tests that are run multiple times per day and it takes about 1.5 hours to complete a full run on that bank. The key is that we wrote our own GUI automation over the years. All we do is send keystrokes and mouseclicks to the UI. However, there are several caveats that we have developed over the years to make it work. 1. the test case NEVER contains screen coordinates. We have methods like ClickOnMenu(aMenu:TMenu,'File|Open'). That method queries the TMenu and finds coordinates of the 'file' menu item, clicks on it and finds coordinates of the open menu item, then clicks on it. Similar is ClickOnControl(form:TForm;control:TControl). The testing system finds the open form, finds the control. finds the coordindates and then sends a mouse click in the middle of the control. There are other variants if you dont exactly want to click in the middle. So in the test is says ClickOnControl(form1, form1.button1). That way, if the developer changes the form, i.e. moves button1 around, then the test is fine. If they delete button1, the test stops compiling. That being said, we wrote tons of these types of methods that are specific for the controls we use, to accommodate their oddities, like virtual string tree etc. It did not happen overnight. 2. We have a small delay after every input except certain cases. This small delay is generally enough. We also have hooked into the idle processing of the program so after sending a mouseclick / keyboard press it waits for the onIdle so the program is not processing more messages. There are a few more tricks as well. However, the upshot is that we rarely have a problem with timing any longer. For really variable processes, we have our GUI automation thread wait on a TEvent in the program and the program triggers the TEvent when the process is done so that the test knows to continue. But that is rare. Not so similar from an end user, that just sits there waiting for the screen to refresh. So, the upshot is that it was a lot of work, and likely only worth it if you are going to maintain the same program for a long time. But it can be done and today, new developers in our company have no idea the hard work that went into it and they just write scripts in a fairly high level way and the infrastructure does the rest. The test cases find the problem they are designed to test, about 50% of the time. The rest of the failures are because of bugs that are involved in things the test was doing to get to the point where it was trying to test. The other upshot is that we very, very rarely have regressions. The vast, vast majority of bugs that make it to production are in new features that have not (in hindsight) been sufficiently testing.
-
How to detect when control is scrolled into view
Anders Melander replied to PiedSoftware's topic in VCL
Something like this? (untested, just a guess) interface type TMyFrame = class(TFrame) private FHasLoaded: boolean; protected procedure PaintWindow(DC: HDC); override; procedure DoLoadFrame; end; implementation procedure TMyFrame.PaintWindow(DC: HDC); begin if (not FHasLoaded) then DoLoadFrame; inherited; end; procedure TMyFrame.DoLoadFrame; begin FHasLoaded := True; // Do load stuff here... end; Of course the frames has to be created before they can be scrolled into view but you can defer loading the frame content. I would probably solve the problem in a different way but I think the above does what you asked for. -
Oz-SGL, a new generic collections library based on the idea of C++ STL
Stefan Glienke replied to Edwin Yip's topic in Algorithms, Data Structures and Class Design
So instead of adressing those statements you bring up some completely irrelevant and wrong things about my library? Well... I am all for criticism if you find issues in its design or implementation but that was just a low blow. 😉 Maybe I am missing something when setting up the list or using the wrong one but there is clearly the lack of handling managed types in TsgList<T> because it simply calls TslListHelper.SetItem which uses ordinal assignments or System.Move. Here is some code that shows that something is wrong - shouldn't it print 0 to 9? But it does print an empty line and then raises an EInvalidPointer. const COUNT = 10; procedure RunSGL; var list: TsgList<string>; i: Integer; s: string; begin list.From(nil); for i := 0 to COUNT-1 do begin s := i.ToString; list.Add(s); end; s := ''; for i := 0 to COUNT-1 do begin s := list[i]; Writeln(s); end; end; P.S. You can edit your posts - no need for multiposting to address multiple previous comments. -
TMemo - How to select (highlight) a line of text in code?
Lajos Juhász replied to Incus J's topic in FMX
Looks like a bug, but you can do: var x: TCaretPosition; begin x.Line:=5; x.Pos:=1; MyMemo.Model.SelectText(x, 50); (Using Delphi XE5 in that version Selstart and Sellength worked as expected.) -
An XML DOM with just 8 bytes per node
Erik@Grijjy replied to Erik@Grijjy's topic in Tips / Blogs / Tutorials / Videos
Then maybe now is a good time to upgrade to the latest Delphi version😉