【发布时间】:2010-11-27 16:26:12
【问题描述】:
你能告诉我在使用中是否有一些优势(更少的存储空间,提高速度等):
resourcestring
MsgErrInvalidInputRange = 'Invalid Message Here!';
而不是
const
MsgErrInvalidInputRange : String = 'Invalid Message Here!';
【问题讨论】:
标签: delphi
你能告诉我在使用中是否有一些优势(更少的存储空间,提高速度等):
resourcestring
MsgErrInvalidInputRange = 'Invalid Message Here!';
而不是
const
MsgErrInvalidInputRange : String = 'Invalid Message Here!';
【问题讨论】:
标签: delphi
const 选项会比 resourcestring 更快,因为后者会调用 Windows API 来获取资源文本。 您可以通过使用一些缓存机制使其更快。这就是我们在增强型 Delphi RTL 中所做的。
如果您必须多次访问资源字符串内容,最好先将资源字符串加载到字符串中。
resourcestring 的要点是允许你的程序进行 i18n(国际化)。
您已经获得了带有某些版本的 Delphi IDE 的翻译管理器。但它依赖于外部 DLL。
您可以使用来自 Linux 世界的 gettext 系统,来自 http://dxgettext.po.dk,它依赖于外部 .po 文件。
我们在我们的框架中包含了我们自己的 i18n 机制,它翻译和缓存资源字符串文本,并依赖于外部 .txt 文件(您可以使用 UTF-8 或 Unicode 文本文件,从 Delphi 6 到 XE)。缓存使其与 const 使用一样快。见http://synopse.info/fossil/finfo?name=SQLite3/SQLite3i18n.pas
还有其他开源或商业解决方案。
关于大小存储,resourcestring存储为UC2缓冲区。因此,直到 Delphi 2009,resourcestring 将使用比字符串更多的内存。自 Delphi 2009 以来,所有字符串都是 unicodestring,即 UCS2,因此您不会有更多的存储空间。在所有情况下,文本的存储大小并不是应用程序更大的大小参数(位图和代码大小对最终 exe 的影响要大得多)。
【讨论】:
资源字符串在您的 exe 资源中存储为 STRINGTABLE 条目,常量存储为固定数据段的一部分。由于它们是资源部分的一部分,您可以提取它们和 DFM、翻译它们并将它们存储在资源模块(仅数据 DLL)中。当一个 Delphi 应用程序启动时,它会查找该 DLL 并将使用其中的字符串而不是包含在您的 EXE 中的字符串来加载翻译。
Embarcadero docwiki 使用 Translation Manager 进行覆盖,但许多其他 Delphi 翻译工具也使用资源字符串。
【讨论】:
正如其他人所提到的,resourcestring 字符串将包含在您的 exe 中的单独资源中,因此当您需要在应用程序的 UI 中满足多种语言时,它具有优势。
正如一些人所提到的,常量字符串包含在应用的数据部分中。
截至 2007 年
在直到 D2007 的 Delphi 版本中,const 字符串存储为 Ansi 字符串,每个字符需要一个字节,而资源字符串将以 UTF-16 存储:Windows 默认编码(尽管可能不适用于 Win9x)。 IIRC D2007 和之前的版本不支持 UTF-8 编码的单元文件。因此,在您的源代码中编码的任何字符串都必须得到 ANSI 代码页的支持,因此可能不会超出 Unicode 基本多语言平面。这意味着将只使用 UTF-16 的 UCS-2 部分,并且所有字符串可以存储在每个字符两个字节中。
简而言之:最多 D2007 const 字符串每个字符占用一个字节,资源字符串每个字符占用两个字节。
D2009 及更高版本
Delphi 在 D2009 版本中启用了 unicode。从那时起,情况就有些不同了。 Resourcesstring 字符串仍以 UTF-16 格式存储。这里没有其他选项,因为它们是由 Windows“管理”的。
然而,Consts 字符串是一个完全不同的故事。自 D2009 以来,Delphi 将每个 const 字符串的多个版本存储在您的 exe 中。每个版本采用不同的编码。 const 可以存储为 Ansi 字符串、UTF-8 字符串和 UTF-16 字符串。
存储哪些编码取决于 const 的使用。默认情况下将使用 UTf-16,因为这是默认的内部 Delphi 编码。将相同的 const 分配给“普通”(UTF-16)字符串以及 AnsiString 变量,该 const 将存储在 UTF-16 和 Ansi 编码的 exe 中...
重复数据删除
从外观上看(用 D5 和 D2009 进行实验),Delphi “de-dupes” const 字符串,而它不会对资源字符串执行此操作。
【讨论】:
使用 resourcestring,编译器将这些字符串作为字符串表资源放置在可执行文件中,允许任何人(比如您的翻译团队)使用资源编辑器编辑它们,而无需重新编译应用程序或访问源代码。
【讨论】:
还有第三种选择:
常量 MsgErrInvalidInputRange = '这里有无效消息!';
后者应该是更高性能的,因为告诉编译器不要在数据段中分配空间,它可以将字符串放在代码段中。还要记住,可以用类型常量做什么取决于 $WRITEABLECONST 指令,尽管我不知道编译器究竟什么时候打开或关闭。
【讨论】:
asm S db 'foo' 和一些技巧将 OFFSET S 传递到外部范围。 IIRC,可写类型常量和初始化变量是完全等价的。