Delphi code optimization - character string

zhaozj2021-02-08  306

Keywords: Delphi, Anisstring, Pcharfreewizard

Delphi has three string types: short string (string [n], n = 1..255) storage area is static allocation, the size is determined when compiling, which is inherited in the type of BP for DOS; character array (PCHAR) It is mainly to be compatible with various types of APIs, which have appeared in BP7, and now more applications in Delphi, and the storage area can be staticly allocated with a character array, or it can be manually assigned by getMem; while long strings (ANSISTRING) is Delphi unique The stored area is dynamically allocated at runtime, the most flexible is also most easily abused.

Do not repeat the initialization of Delphi default string type ANSISTRING automatically initializes empty. As follows:

Var s: string; begins: = ''; ... End; s: = ''; there are more than one. But it is worth noting that this is invalid if the function return value Result is invalid. In general, the use of VAR-in-arguments is more faster than returning string values.

Using SETLENGTH pre-allocation of long strings (ANSISTRING) dynamic allocation of memory is a large length of Ansistring, but it is easy to get into a typical example: S2: = '; for i: = 2 to Length (S1) DO S2: = S2 S1 [I]; and not to say that DELETE can be replaced, the main problem is that the memory area of ​​S2 in the loop in the previous example is constantly repeated, and it is quite a fee. A simple and effective approach is as follows: setLength (S2, Length (S1) -1); for i: = 2 to length (S1) DO S2 [I-1]: = S1 [i]; this S2 memory will only be redistributed once.

String and dynamic array thread security (Thread Safety) Dynamic array in Delphi 5 This non-threaded security call is handled by the reference count to handle its critical problems, and it is changed directly from Delphi5. Critical instructions plus the LOCK instruction prefix to avoid this problem. Unfortunately, this modification is quite expensive, because at the PentiumII processor, the Lock instruction is quite cost, and the extra 28 instruction cycles is taken to complete this operation, so the overall efficiency is at least half. The way to solve this problem is only one, that is, modify the Delphi RTL core code. After backing up the original file, replace all LOCK in Source / RTL / Sys / System.PAS is {Lock}, of course, must be an internal change. The next step is not fully optimized, the next step is to remove the XCHG instructions in the Delphi4 running library, because the instruction has an implicit Lock prefix, so you must use the system.pas _lstrasg and _Strlasg xchg EDX, [EAX] Replace with the following code: MOV ECX, [EAX] MOV [EAX], EDXMOV EDX, ECXOK is highly refined, compiled, override the system.dcu. So, the performance efficiency will be increased by 6 times higher than Delphi5, 2 times higher than Delphi4.

Avoid using short strings Since a lot of string operations will convert short strings to a long string, slowing down the execution speed, so it is still less short-character strings.

Avoid using a COPY function This is also related to abuse of memory management. A typical situation is as follows: if Copy (S1, 23, 64) = COPY (S2, 15, 64) Then ... thus caused two temporary memory, thus reducing efficiency. It should be replaced with the following code: i: = 0; f: = false; repeat f: = S1 [i 23] <> S2 [i 15]; INC (i); until f or (i> 63); if NOT F THEN ... Similarly, the following statement is quite inefficient: s: = COPY (S, 1, Length (s) -10); should be changed to delete (s, length (s) -10, 10); By the way, when the string is connected, S: = S1 S2; simple and effective; but under delphi2, S: = Format ([% S% S], S1, S2); may be slightly faster. Always use long strings, convert to PCHAR when necessary to see the definition of Ansistring: Type Astring = Packed Record Allocsiz: longint; // Dynamic allocation size refcnt: longint; // Reference count Length: longint; // actual length chron : array [1..allocsiz-6] of char; // byte sequence end; intring [1] will return the contents of Astring.chrarr [1]. Many people think that Ansistring is naturally inefficient. In fact, this is largely caused by poor code, memory management, and lack of supported functions. As mentioned above, once the dynamic is allocated, a long string is a linear byte sequence, and does not matter of efficiency. Of course, if there is more effective functions, it is better. Speaking of the conversion of Ansistring to PCHAR, there are three ways: (1) P: = @ s [1]; this will trigger uniqueString calls. (2) P: = pchar (s); This will check if S is empty. If yes, return nil, otherwise returns the address of S [1]. (3) P: = Pointer (s); this does not trigger any implicit calls, thus determining the best choice for S non-empty conditions.

转载请注明原文地址:https://www.9cbs.com/read-1255.html

New Post(0)