Leaderboard
Popular Content
Showing content with the highest reputation on 11/27/20 in all areas
-
How to optimize exe loading times
Lars Fosdal replied to a topic in Software Testing and Quality Assurance
Rule #1 - Don't do shit before your application has loaded and displayed itself. After the initial display, you can show various "Preparing good stuff - % complete" messages and do stuff in threads, allowing basic interaction with the app - such as doing an immediate exit. Speed is mostly about perception. -
@Stefan Glienke You're unbelievable man ! The next time I'm going to demonstrate something ... I'll make sure that Stefan will not find a link between the input and the output (hmm TRNGs)
-
How to optimize exe loading times
Rollo62 replied to a topic in Software Testing and Quality Assurance
Oh so 20's: Today, I say "Alexa, kill bill" Next year, I think: "GPT-3, optimize Windows and solve my customer Scott's code issues" -
RTFBody is an array of byte, each byte is an ASCII character, the last one being #0. You can consider this as being a C string type. To save it to a file, you can write: procedure TForm1.Button1Click(Sender: TObject); var ANameSpace : Variant; AFolderItem : Variant; AMailItem : Variant; RTFBody : array of Byte; Stream : TFileStream; begin OutlookApplication1.Connect; ANameSpace := OutlookApplication1.GetNameSpace('MAPI'); AFolderItem := ANameSpace.GetDefaultFolder(olFolderInbox); AMailItem := AFolderItem.Items(1); RTFBody := AMailItem.RTFBody; Stream := TFileStream.Create('RTFBody.rtf', fmCreate); try Stream.Write(RTFBody[0], Length(RTFBody)); finally Stream.Free; end; end; If you want to convert to a string here is a possibility: Get it into an AnsiString using SetString. Convert the AnsiString to String (Unicode). Now you can handle it as any other string. Here is some example code to display the first email body in a TMemo: procedure TForm1.Button1Click(Sender: TObject); var ANameSpace : Variant; AFolderItem : Variant; AMailItem : Variant; RTFBody : array of Byte; RTFAnsiString : AnsiString; RTFString : String; begin OutlookApplication1.Connect; ANameSpace := OutlookApplication1.GetNameSpace('MAPI'); AFolderItem := ANameSpace.GetDefaultFolder(olFolderInbox); AMailItem := AFolderItem.Items(1); RTFBody := AMailItem.RTFBody; SetString(RTFAnsiString, PAnsiChar(@RTFBody[0]), Length(RTFBody)); RTFString := String(RTFAnsiString); Memo1.Lines.Add(RtfString); end; Don't forget to add error checking in the code (No Outlook, no mail, empty mail,...).
-
How to optimize exe loading times
Clément replied to a topic in Software Testing and Quality Assurance
Since your concern is about startup time, there's a very handy way to find the culprit: Comment your code. All the objects( data modules, forms, classes ) created before the "application.run" should be checked for "legacy code not required anymore" If your project starts creating only the main form, then check the constructor and show form. And don't be shy! comment everything! even assignments (you never know what a setter might be doing) You will find out some leftovers from the past, that made perfect sense last decade, that are no longer required. The library you are using are among the best in delphi ecosystem, but... since you mention IBObjects, and FireDac, are you sure there's no query being executed at startup? DB Stuff might usually be rather slow, specially if some event's are alive during startup! -
Byte Array to String
David Heffernan replied to Mark Williams's topic in RTL and Delphi Object Pascal
If it's a byte array, why don't you just write that to file? Why do you need to convert it to a string variable? -
How to optimize exe loading times
Lars Fosdal replied to a topic in Software Testing and Quality Assurance
Why? Because not seeing the application work is easy to confuse with seeing the application not working. -
Well, you shouldn't really be solving that by giving the application full access to everything - but that's a different issue.
-
HTML Library review and sale: 25% off.
microtronx replied to Alexander Sviridenkov's topic in Delphi Third-Party
Very stable and good components + very good support. We can recommend htmlcomponents fully! Thanks for your work Alexander! -
HTML Library review and sale: 25% off.
Alexander Sviridenkov replied to Alexander Sviridenkov's topic in Delphi Third-Party
@dummzeuch full source code is included for all licenses / products. Also it includes one year of support and all updates (major/minor). -
How to optimize exe loading times
Stefan Glienke replied to a topic in Software Testing and Quality Assurance
SamplingProfiler usually gives a good overview to find the particularly time consuming parts. (although it says up to XE4 on that page it works just fine for up to 10.4) -
Micro optimization - effect of defined and not used local variables
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
As a guideline: try to remove overhead from prologues and epilogues caused by variables of managed types (explicit or implicit) such as strings or interfaces that are only there for the uncommon path. Another example was the error raising code in the hextobin thread that can be put into a subroutine that gets called only when the rase case of a invalid char occurs. Eric Grange wrote a nice article about this some years ago that I like to recommend: https://www.delphitools.info/2009/05/06/code-optimization-go-for-the-jugular/ -
@David Heffernan Few remarks about your code if you don't mind : 1- Its pointless to use string when characters are fixed in size ... Simply use static array of X char. 2- Its also pointless to calculate index when you already used a case ... Simply declare your array using char-range. In your case, compiler generated additional instructions to compute the index. function HexToBin2(const HexValue: string): string; type TChar4 = array [0 .. 3] of Char; PChar4 = ^TChar4; const Table1: array ['0' .. '9'] of TChar4 = ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001'); Table2: array ['a' .. 'f'] of TChar4 = ('1010', '1011', '1100', '1101', '1110', '1111'); var HexDigit: Char; P: PChar4; begin SetLength(Result, Length(HexValue) * 4); P := PChar4(Result); for HexDigit in HexValue do begin case HexDigit of '0' .. '9': P^ := Table1[HexDigit]; 'a' .. 'f': P^ := Table2[HexDigit]; 'A' .. 'F': P^ := Table2[Chr(Ord(HexDigit) xor $20)]; else raise EConvertError.CreateFmt('Invalid hex digit ''%s'' found in ''%s''', [HexDigit, HexValue]); end; Inc(P); end; end;
-
I'd probably write it something like this: function HexToBin(const HexValue: string): string; const BinaryValues: array [0..15] of string = ( '0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111' ); var HexDigit: Char; HexDigitValue: Integer; Ptr: PChar; begin SetLength(Result, Length(HexValue) * 4); Ptr := Pointer(Result); for HexDigit in HexValue do begin case HexDigit of '0'..'9': HexDigitValue := Ord(HexDigit) - Ord('0'); 'a'..'f': HexDigitValue := 10 + Ord(HexDigit) - Ord('a'); 'A'..'F': HexDigitValue := 10 + Ord(HexDigit) - Ord('A'); else raise EConvertError.CreateFmt('Invalid hex digit ''%s'' found in ''%s''', [HexDigit, HexValue]); end; Move(Pointer(BinaryValues[HexDigitValue])^, Ptr^, 4 * SizeOf(Char)); Inc(Ptr, 4); end; end; Some notes: A case statement makes this quite readable in my view. You really don't want to be wasting time using Pos to search within a string. You can get the value directly with arithmetic. I prefer to perform just a single allocation, rather than use repeated allocations with concatenation. You might want to consider how to treat leading zeros. For instance how should you treat 0F, should that be 00001111 or 1111? I'd expect that both would be desirable in different situations, so an option in an extra argument to the function would be needed.