0

I am a "performance" enthusiast programmer, and have a basic theoretical question: Does Delphi 7 has some "way" to identify the kind of string used and automatically define the correct type?

For example, when you know the result string length from a function will always be shorter than 255, would you use:

function SomeFunction: String; or function SomeFunction: ShortString;?

Same thought with:

function SomeFunction(Num: Integer): Integer; or function SomeFunciont(Num: Byte): Word;?

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
Guybrush
  • 1,575
  • 2
  • 27
  • 51
  • Asking "How do I optimize something I haven't done yet?" is meaningless. Write your code. If it performs too slowly, use a profiler to identify where the performance problem is located, and then worry about how to fix that bottleneck. – Ken White Apr 07 '13 at 07:50
  • Please Ken, can you explain us more about "profiler" ? You mean something like FastMM4 ? – Guybrush Apr 07 '13 at 07:58
  • No, I don't mean FastMM4. (FastMM is a memory manager, not a profiler.) Google "profiler Delphi". You need to start doing basic research yourself before posting questions here. – Ken White Apr 07 '13 at 08:01
  • 1
    Judging by your recent questions you are looking in the wrong place for performance gains. The way to make your programs perform better is to use good algorithms. Your recent questions displayed some exceptionally inefficient algorithms. Always start by looking at your algorithms. – David Heffernan Apr 07 '13 at 12:26
  • Welcome to Stack Overflow. I'd never expect a "performance enthusiast" to ask this sort of question. It's something you should be excited about discovering for yourself. Maybe you'd *like* to be a performance enthusiast, and your question should be about *how* you would answer a performance question. – Rob Kennedy Apr 07 '13 at 12:42
  • David is (as always) right: algorithm is the key to speed. A book worth reading is http://www.lulu.com/shop/julian-m-bucknall/the-tomes-of-delphi-algorithms-and-data-structures/ebook/product-20734252.html - even if it is now brand new, it is the best algorithm book for Delphiers around, IMHO. – Arnaud Bouchez Apr 07 '13 at 18:29
  • Well, not always, but certainly here. I'd add to what @Arnaud says that you need to be able to read non-Delphi sources to learn about algos. Algorithms are language neutral and the best reference material will not use Pascal. – David Heffernan Apr 07 '13 at 22:14

2 Answers2

4

Never use shortstring with functions, even in Delphi 7.

When used as a function result, a shortstring full content (i.e. all characters) is always copied.

So it will be slower than using a plain string variable, which will only increment the internal reference count of the string, without copying the chars.

Since most of the Delphi RTL/VCL libraries use string, using shortstring in your code will add a lot of conversions for each call of those methods, whereas it will not be the case when using plain string. And when calling the Windows API, the delphi string type is already zero-ended, so will avoid any allocation and conversion, which is necessary when using shortstring.

Therefore, you have to know that shortstring is slower in all versions of Delphi, especially if you use FastMM4 as memory manager: when using the shortstring for any RTL/VCL/API calls, the Delphi compiler will in fact allocate some hidden temporary string, therefore allocate a buffer from the heap... far from efficient: it is preferred to use a string right away!

If you think that string is slow (due to the atomic reference counting or memory allocation which are not so multithread-friendly), do not use shortstring, but other structures - see my answer https://stackoverflow.com/a/6076407/458259 And never optimize without profiling with a tool like http://delphitools.info/samplingprofiler/

For functions using integer values, byte/word/cardinal/integer does not make a speed difference. My habit is to use integer whenever possible, which will fit the CPU register size. Only Int64 kind of value will be slower, under 32 bit, since it will use 2 registers or a temporary variable on stack.

Update: with newer versions of Delphi, you will have the "inline" keyword, which may help a lot about performance of small functions returning such types. And since Delphi 2009, string is Unicode and shortstring is deprecated, since it is fixed to the System Non-Unicode applications code page. Use shortstring only if you know exactly what you are doing, and are able to use Alt-F2 and see the generated asm code, guessing which hidden RTL functions are called.

Community
  • 1
  • 1
Arnaud Bouchez
  • 42,305
  • 3
  • 71
  • 159
  • Thank you Arnaud! It is exactly what I'd like to know! – Guybrush Apr 07 '13 at 08:32
  • Your no shortstring-as-function-result assumption is correct, at least with current optimization levels. But if you exclude that, then in situations where ansistring can't leverage a significant copy-on-write advantage shortstring should still be faster, if only because the refcounting procedure calls and allocation are then only extra overhead. Shortstring has many shortcomings, but its main problem is labeled in the name, and it is not "noperformancestring" :) I also don't understand what fastmm has to do with it. – Marco van de Voort Apr 07 '13 at 13:08
  • @MarcovandeVoort In Delphi 7 - which is OP's version - the heap manager was very slow, so in this case string allocation was much slower than stack-allocated shortstring. If you use FastMM4 in Delphi 7, this slowness factor disappears. I never wrote never to use shortstrings, just never with functions, RTL or APIs. ShortString will create temporary copies with a length of 255 chars on the stack for most of its operations (like assignment, concatenation or such), so are of little benefit, unless you deeply know the Delphi RTL. Most of the type, a stack-allocated char buffer is a better idea. – Arnaud Bouchez Apr 07 '13 at 18:17
  • But the copies on the stack are free or near free (simply added to the size of the stckframe), while in similar cases an ansistring based temp involves calling helper procedure and the heapmanager, unless it is solely used as a 1:1 copy. (and btw, IMHO fastmm's gains are sometimes exaggerated) – Marco van de Voort Apr 07 '13 at 21:23
  • @MarcovandeVoort With real profiling, FastMM4 gain is about 3x-5x for most allocations, for mono-threaded applications, in respect to the old Borland MM. About copy on the stack of a `shortstring`, it is not free, I'm afraid you did not step in the generated asm. The memory is allocated inline in the stack frame prolog, *but* the copy is done with a RTL call, and a nested `move()` - see `_PStrCpy()` in `system.pas` - whereas a `string` copy is just a `lock inc [refCount]`. *Much* faster. Generaly, `_PStr*` functions or compiler-generated opcodes are slower (e.g. `rep movsb` on modern CPU). – Arnaud Bouchez Apr 08 '13 at 08:59
  • Thats the "solely 1:1 copy" case. Most actually modify strings, and then an allocation is quickly needed (and cheaper in the stack based case). I find it strange to be defending shortstring though, I've tried to get them exterminated for years. – Marco van de Voort Apr 08 '13 at 11:41
0

Does Delphi 7 have some way to identify the kind of string used and automatically define the correct type?

Even if it improved performance, the compiler never makes such transformations. In order to do so it would need to perform what is known as data flow analysis. In other words it would need to analyse how the data flows through the program and reason about the possible content that could be held in variables.

But the compiler does not perform that sort of analysis and so cannot make optimisations of the type you describe.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • @user539484 What did you dislike about this answer? Does it fail to address the question that was asked? Or is it factually incorrect? – David Heffernan Apr 08 '13 at 19:24