24

Would you tell me if there is some advantage (less sotorage space, increase speed, etc) in using:

resourcestring
    MsgErrInvalidInputRange = 'Invalid Message Here!';

instead of

const
    MsgErrInvalidInputRange : String = 'Invalid Message Here!';
Gedean Dias
  • 1,063
  • 1
  • 10
  • 24

5 Answers5

17

The const option will be faster than resourcestring, because the later will call the Windows API to get the resource text. You can make it faster by using some caching mechanism. This is what we do in our Enhanced Delphi RTL.

And it's a good idea to first load the resourcestring into a string, if you'll have to access many times to a resourcestring content.

The main point of resourcestring is to allow i18n (internationalization) of your program.

You've got the Translation Manager with some editions of the Delphi IDE. But it relies on external DLL.

You can use the gettext system, coming from the Linux world, from http://dxgettext.po.dk which relies on external .po files.

We included our own i18n mechanism in our framework, which translates and caches the resourcestring text, and relies on external .txt files (you can use UTF-8 or Unicode text files, from Delphi 6 up to XE). The caching make it quite as fast as the const usage. See http://synopse.info/fossil/finfo?name=SQLite3/SQLite3i18n.pas

There are other open source or commercial solutions around.

About size storage, resourcestring are stored as UC2 buffers. So resourcestring will use more memory than string up to Delphi 2009. Since Delphi 2009, all string are unicodestring i.e. UCS2, so you won't have much more storage size. In all cases, storage size of text is not the bigger size parameter for an application (bitmaps and code size have a much bigger effect to the final exe).

Arnaud Bouchez
  • 42,305
  • 3
  • 71
  • 159
  • Will it actually call the windows api if the resource system is not intialized? (iow no translations loaded) Haven't stepped through Delphi, but FPC doesn't. dxgettext is great (and I prefer it over ITE), but it has downsides too, specially wrt resourcestrings – Marco van de Voort Nov 28 '10 at 11:55
  • @Marco: of course, the Windows API is always called, even if no translation is loaded. Check the LoadResString() procedure in System.pas – Arnaud Bouchez Nov 28 '10 at 15:44
7

Resource strings are stored as STRINGTABLE entries in your exe resource, consts are stored as part of the fixed data segment. Since they're part of the resource section you can extract them and the DFMs, translate them, and store them in a resource module (data-only DLL). When a Delphi app starts, it looks for that DLL and will use the strings from it instead of the ones included in your EXE to load translations.

The Embarcadero docwiki covers using the Translation Manager, but a lot of other Delphi translation tools use resource strings too.

Zoë Peterson
  • 13,094
  • 2
  • 44
  • 64
  • 2
    Resources are a de-facto standard under Windows to localize applications. The translation editor and other tools also can modify .dfms which are stored as resources also. The advantage is that not only strings, but even control sizes, positions, colors and images can be tailored to the target "culture", something that cannot be done using tools that translates only strings. –  Nov 27 '10 at 18:15
  • FPC 2.4.0+ supports the mechanism anywhere for resourcestrings. Lazarus afaik doesn't store its dfm's in resources yet though, but this might change short term, still Lazarus is still going through a 2.2->2.4 transition – Marco van de Voort Nov 28 '10 at 11:58
  • @ldsandon: you can customize resourcestring and dfm on the fly, without any resource modification. That's what dxgettext and our unit do, by hooking some VCL calls (like LoadResString or TCustomForm.Create). – Arnaud Bouchez Nov 28 '10 at 15:45
6

As others have mentioned, resourcestring strings will be included in a separate resource within your exe, and as such have advantages when you need to cater for multiple languages in the UI of your app.

As some have mentioned as well, const strings are included in the data section of your app.

Up to D2007

In Delphi versions up to D2007, const strings were stored as Ansi strings, requiring a single byte per character, whereas resource strings would be stored in UTF-16: the windows default encoding (though perhaps not for Win9x). IIRC D2007 and prior versions didn't support UTF-8 encoded unit files. So any strings coded in your sources would have to be supported by the ANSI code pages, and as such probably didn't go beyond the Unicode Basic Multilingual Plane. Which means that only the UCS-2 part of UTF-16 would be used and all strings could be stored in two bytes per character.

In short: up to D2007 const strings take a single byte per character, resource strings take two bytes per character.

D2009 and up

Delphi was unicode enabled in version D2009. Since then things are a little different. Resourcestring strings are still stored as UTF-16. No other option here as they are "managed" by Windows.

Consts strings however are a completely different story. Since D2009 Delphi stores multiple versions of each const string in your exe. Each version in a different encoding. Const can be stored as Ansi strings, UTF-8 strings and UTF-16 strings.

Which of these encodings is stored depends on the use of the const. By default UTf-16 will be used, as that is the default internal Delphi encoding. Assign the same const to a "normal" (UTF-16) string, as well as to an AnsiString variable, and the const will be stored in the exe both UTF-16 and Ansi encoded...

De-duping

By the looks of it (experimenting with D5 and D2009), Delphi "de-dupes" const strings, whereas it doesn't do this for resourcestring strings.

Marjan Venema
  • 19,136
  • 6
  • 65
  • 79
  • 4
    The de-duping bit is logical. Two words that are the same in the "app built-in language" might have multiple meanings when translated, depending on context. – Marco van de Voort Nov 28 '10 at 11:57
  • The "one byte per character" and "two bytes per character" is not true in case of MBCS (like asiatic) charsets. But it's true in case of English/West European languages (code page 1252). In all cases, as I stated in my answer, resourcestring size doesn't matter much for the final exe size (bitmaps and code matter more). – Arnaud Bouchez Nov 28 '10 at 15:49
  • @A.Bouchez: indeed yes, for delphi versions up to D2007 there would not have been a difference in bytes per character when using the MBCS code pages. – Marjan Venema Nov 28 '10 at 15:55
2

With resourcestring, the compiler places those strings as a stringtable resource in the executable, allowing anyone (say your translation team) to edit them with a resource editor without needing to recompile the application, or have access to the source code.

Frederik Slijkerman
  • 6,471
  • 28
  • 39
1

There's also a third options that is:

const MsgErrInvalidInputRange = 'Invalid Message Here!';

The latter shoud be the more performant one because tell the compiler to not allocate space in the data segment, it could put the string in the code segment. Also remember that what coould be done with typed constants depends on the $WRITEABLECONST directive, although I do not know what the compiler exactly when it is on or off.

  • Good one! I missed what constant in original post is typed. Overhead for typed vs. true constant is pointer dereferencing. However, both string will go .data section anyways. Putting some data in code segment requires `asm S db 'foo'` and some trick to pass OFFSET S to the outer scope. IIRC, writable typed constants and initialized variables are completely equivalent. – Free Consulting Nov 27 '10 at 19:15
  • Storing data in the code segmente is possible, and no trick is required, as long as the segment is readable and not only executale. What I do not know if the Delphi compiler does it still or not, I am sure the old TP one did. Also AFAIK it's not documented how true constants and typed constants are stored and handled. –  Nov 28 '10 at 13:10
  • This won't be "more performant". It will be encoded exactly the same if stored in data or in code section. – Arnaud Bouchez Nov 28 '10 at 15:52
  • Cache performance will likely favour the string being declared adjacent to the code that uses it – David Heffernan Nov 28 '10 at 19:43