Leaderboard
Popular Content
Showing content with the highest reputation on 03/23/22 in all areas
-
Why isn't this dangerous, or is it?
Attila Kovacs replied to Renate Schaaf's topic in Algorithms, Data Structures and Class Design
Well, it was the last option 😉 As the example shows, this pattern hiding something from you. It's not your friend. Do not underestimate that. With time, you won't remember everything. I mean, a thing. You won't remember anything. 😉 -
Several F2084 Internal Error on Delphi 10.4.2
mvanrijnen replied to Davide Angeli's topic in Delphi IDE and APIs
Problem is that many of these type of errors, expose only in larger projects. -
CMD /C Run Command and then terminate CMD /K Run Command and then return to the CMD prompt. This is useful for testing, to examine variables
-
Several F2084 Internal Error on Delphi 10.4.2
Lars Fosdal replied to Davide Angeli's topic in Delphi IDE and APIs
Closed as cannot reproduce. Without sample code that actually can reproduce the problem, it is impossible to resolve the cause. -
It is a problem that you have zero error handling around the Win32 operations in the Cmd method. Without the precise error information from the failing API(s), we are completely in the dark. F.x. if CreateProcess fails, you need to call GetLastError and log or pass on the error info somehow. Almost every Win32 API method will update last error.
-
DXBuild is a **free** command-line tool. It makes it easier to build multi-version Delphi projects (Delphi 2007 or newer, dproj/groupproj). Example dxbuild Packages\DelphiXE2\Spring.Base.dproj -d DelphiXE2 -p Win32 Win64 -c Debug Release Benefits - Compile faster with fastdcc (Delphi 2009 - 10.3) https://www.idefixpack.de/blog/ide-tools/ide-fix-pack/ NOTE: For Delphi XE3 or higher, you just need to download and extract fastdcc*.exe to `$(BDS)\bin`. dxbuild will use fastdcc when possible. Use `--no-fastdcc` to disable it. Download: https://devjetsoftware.com/download/2009/ Report Issues: https://github.com/devjetsoftware/dxbuild-public
-
Micro optimization: IN vs OR vs CASE
David Heffernan replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
What proportion of the overall time your program takes for the task, is the operation you are trying to optimise in this thread? -
Micro optimization: IN vs OR vs CASE
Lars Fosdal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Typed consts are not consts unless you type them on the right side of the expression. const NotAConst: Integer = -1; IsAConst = Integer(-1); The record type simply becomes a "scope" for const declarations. Benefit: the consts can be non-uniquely named without polluting your name spaces since you always need to prefix with the type name to access the const. Added bonus - you can have methods in the record declaration that can deal with logical operations related to the constants. type cButton = record const ThisIsFine = mrOK; end; cAnswer = record const ThisIsFine = String('This is fine'); end; cLimit = record const ThisIsFine = Double(3.14); end; -
Micro optimization: IN vs OR vs CASE
Lars Fosdal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
type xConst = record const ButtonId = 1; end; procedure Test; var bId: Integer; begin bId := xConst.ButtonId; end; -
Why isn't this dangerous, or is it?
corneliusdavid replied to Renate Schaaf's topic in Algorithms, Data Structures and Class Design
I don't think I've ever seen a procedure of a class free the instance of the class it's being called from. Everything in me is screaming DON'T DO IT! This is very bad practice. The object code may still be in memory after the call to Free but it's no longer dedicated to that object and if, per chance, some other operation suddenly uses that available memory, you've got an access violation. And to make an example that shows the problem of the dangling pointer @Attila Kovacspoint out: procedure TForm1.Button1Click(Sender: TObject); begin var DoSomething: TDoSomething := TDoSomething.create; DoSomething.DoSomething; if Assigned(DoSomething) then begin ShowMessage('DoSomething Freed but dangling reference still exists'); DoSomething.DoSomething; // <--- ERROR! end; end; It's better to free the memory outside of the class itself in a try-finally block: procedure TDoSomething.DoSomething; begin ShowMessage('Doing something'); end; procedure TForm1.Button2Click(Sender: TObject); begin var DoSomething: TDoSomething; DoSomething := TDoSomething.create; try DoSomething.DoSomething; finally DoSomething.Free; end; end; This makes it obvious from the calling procedure (the button click event) that the object is freed which lessens the likelihood of using it again because it's right there in the procedure instead of hidden in the class itself. -
Why isn't this dangerous, or is it?
David Heffernan replied to Renate Schaaf's topic in Algorithms, Data Structures and Class Design
No I don't think so. Follow the actual rules. When you create an instance, destroy it in the same context that you created it. -
Is Move the fastest way to copy memory?
Arnaud Bouchez replied to dummzeuch's topic in RTL and Delphi Object Pascal
Don't expect anything magic by using mORMot MoveFast(). Perhaps a few percent more or less. On Win32 - which is your target, IIRC the Delphi RTL uses X87 registers. On this platform, MoveFast() use SSE2 registers for small sizes, so is likely to be slightly faster, and will leverage ERMSB move (i.e. rep movsb) on newer CPUs which support it. To be fair, mORMot asm is more optimized for x86_64 than for i386 - because it is the target platform for server side, which is the one needing more optimization. But I would just try all FastCode variants - some can be very verbose, but "may" be better. What I would do in your case, is trying to not move any data at all. Isn't it possible that you pre-allocate a set of buffers, then just consume them in a circular way, passing them from the acquisition to the processing methods as pointers, with no copy? The fastest move() is ... when there is no move... 🙂 -
That's why the mentioned internal programs support redirection with a section like this: [redirect] inifile=some\path\to\another\inifile (and usually nothing else) This will redirect the access to the inifile to a different file. It supports environment variables in the file name and the name can be relative to the main ini file. It gets even more flexible by allowing to redirect sections or even single entries. I'm using something similar in dzPrepBuild to keep version information in sync between several executables belonging to the same project, e.g. GExperts: [Version Info] AutoIncBuild=0 Build=redirect:..\..\SVN_Version.ini,SVN,HighestVersion MajorVer=redirect:..\GExperts_version.ini,Version Info,MajorVer MinorVer=redirect:..\GExperts_version.ini,Version Info,MinorVer Release=redirect:..\GExperts_version.ini,Version Info,Release [Version Info Keys] FileVersion=1.3.4.0 FileDescription=GExperts for Delphi 2007 OriginalFilename={ProjectName}.dll InternalName=GExperts for Delphi 2007 Comments=redirect:..\GExperts_version.ini,Version Info Keys,Comments CompanyName=redirect:..\GExperts_version.ini,Version Info Keys,CompanyName LegalCopyright=redirect:..\GExperts_version.ini,Version Info Keys,LegalCopyright LegalTrademarks=redirect:..\GExperts_version.ini,Version Info Keys,LegalTrademarks ProductName=redirect:..\GExperts_version.ini,Version Info Keys,ProductName ProductVersion=redirect:..\GExperts_version.ini,Version Info Keys,ProductVersion Of course if is that is done excessively you will end up with an unmaintainable set of files.
-
Micro optimization: IN vs OR vs CASE
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
The point that others already have expressed is that despite being interested in a topic as performance improvement so low level (as in instruction-level instead of algorithmic level) you seem to lack some important knowledge to do so such as assembly - it does not require as much as it does to write assembly code but to understand it in order to be able to look at the code in the debugger and see that some comparisons are apples and bananas. I did not even read through your code but simply placed a breakpoint into your IsIN function and noticed that it contained a function call to System.SetElem (that even was the first time I have ever seen that function being called so a TIL for me). Why was that the case? Because you are not using consts here but variables. Had you simply made consts for all those IDs the code would have almost as fast as the IsOR which does not suffer to extra function calls but from memory reads (not noticeable in the benchmark because its all in L1 cache already). On my CPU InOR is still a little faster than IsIN which is due to the fact how the compiler builds the in - you can see that for yourself in the disassembly and then look at instruction timings, read up on macro-operation fusion and data dependency For reference, this is the assembly for the two functions when using consts Project1.dpr.40: Result := aID in [xControlsRec.ButtonID, xControlsRec.FormID, xControlsRec.ListBoxID, xControlsRec.TabControlID, xControlsRec.ComboBoxID]; 004CEE7C 83E802 sub eax,$02 004CEE7F 7417 jz $004cee98 004CEE81 83E802 sub eax,$02 004CEE84 7412 jz $004cee98 004CEE86 83E802 sub eax,$02 004CEE89 740D jz $004cee98 004CEE8B 83E802 sub eax,$02 004CEE8E 7408 jz $004cee98 004CEE90 83E802 sub eax,$02 004CEE93 7403 jz $004cee98 004CEE95 33C0 xor eax,eax 004CEE97 C3 ret 004CEE98 B001 mov al,$01 Project1.dpr.41: end; 004CEE9A C3 ret 004CEE9B 90 nop Project1.dpr.45: Result := (aID = xControlsRec.ButtonID) or (aID = xControlsRec.FormID) or (aID = xControlsRec.ListBoxID) or (aID = xControlsRec.TabControlID) or (aID = xControlsRec.ComboBoxID); 004CEE9C 83F802 cmp eax,$02 004CEE9F 7417 jz $004ceeb8 004CEEA1 83F804 cmp eax,$04 004CEEA4 7412 jz $004ceeb8 004CEEA6 83F806 cmp eax,$06 004CEEA9 740D jz $004ceeb8 004CEEAB 83F808 cmp eax,$08 004CEEAE 7408 jz $004ceeb8 004CEEB0 83F80A cmp eax,$0a 004CEEB3 7403 jz $004ceeb8 004CEEB5 33C0 xor eax,eax 004CEEB7 C3 ret 004CEEB8 B001 mov al,$01 Project1.dpr.46: end; 004CEEBA C3 ret Depending on the number of IDs you have it might be worth using power of two and bitmasks or an enum directly because that would only require one cmp/test making the function twice as fast and perfect for inlining which would then also eliminate the function call overhead at all.