2011-10-13 28 views
1

出于我的目的,我实际上是真正使用ASCII字符数据(用于将ASCII文本文件提交到状态),所以只使用unicodestring将无助于最终结果(我仍然需要转换某些内容)。哪一个需要最大的命中:AnsiString到String或String到AnsiString?

我可以选择将Delphi 2009中的StrComp函数转换为将一个AnsiString和一个PAnsiChar比较为一个UnicodeString和一个PAnsiChar。

Val : PAnsiChar 
Mask : TEditMask; 

....

,这是我的原代码,这不是好

StrComp(PAnsiChar(Mask.EditText), Val); 

....

的话,我可以把它改成这样:

StrComp(PAnsiChar(AnsiString(MAskEdit.EditText), Val); 

或者,我可以将其更改为(额外的co为“清晰”)nversions:

StrComp(PChar(MAskEdit.EditText), PChar(String(AnsiString(Val)))); 

我记得马可坎说,不要做这些中的一个在一个循环中,我不记得哪一个为什么。

+1

就像VCL AnsiStrings单元一样,您可以从kernel32调用CompareStringA(从Windows.pas获取它)。然后你必须从Unicode转换到Ansi。这真的是一个瓶颈吗? –

+0

什么似乎是最大的问题是,当你不断追求不断增长的字符串。 Ala'UnicodeStr:= ANSIStr + UnicodeStr'。我只是不知道这是否比“ANSISTr:= UnicodeStr + AnsiStr”更容易。没关系是一个完全可以接受的答案。 –

+0

为此使用StringBuilder。这个问题是关于堆分配的。尽量减少转换次数。因此,建立没有转换的字符串,然后在最后阶段进行转换。 –

回答

5

如果你编译如下:

StrComp(PAnsiChar(Mask.EditText), Val); 

有从Mask.EditTextUnicodeString的隐式转换到一个临时AnsiString为了让类型投到PAnsiChar。这是您的第2行:

StrComp(PAnsiChar(AnsiString(MAskEdit.EditText), Val); 

但写

StrComp(PChar(MAskEdit.EditText), PChar(String(AnsiString(Val)))); 

会让PChar(MAskEdit.EditText)回报PChar,这是一个PWideChar,所以它会使用其他重载StrComp功能。

事实上,有在SysUtils.pas自2009年以来的Delphi定义两个重载功能:

function StrComp(const Str1, Str2: PAnsiChar): Integer; overload; 
function StrComp(const Str1, Str2: PWideChar): Integer; overload; 

这两个函数都将不会调用Windows API,但将一个接一个比较字符,大小写。

所以我的建议是,你根本就没有使用任何指针在你的代码,但在你的代码string = UnicodeString变量处处依靠平原,使用此功能来代替:

function CompareStr(const S1, S2: string): Integer; 

比较,将在相同,并且不会有隐藏的转换。具有WideChar而不是AnsiChar(即具有两倍内存)的问题与unicode和当前ansi页面之间的转换(两个WinAPI调用)相比没有任何意义。引用您的标题,转换方向并不重要:它总是比没有转换慢很多。

如果您搜索速度问题,我怀疑Mask.EditText确实是您代码中的瓶颈。此方法将发送GDI消息,等待组件的响应,然后通过文本影响string。如果我怀疑你在循环中使用这个Mask.EditText表达式,那么你最好在栈上使用一个临时变量。

2

真正的问题是 - 为什么要比较UnicodeStringPAnsiChar而不是将PAnsiChar数据更新为Unicode?您应该在与传统数据,网络连接等交互的边界处使用AnsiChar/AnsiString。所有内部处理都应使用单个字符串编码来避免这些类型的问题。加载数据时,将旧版/网络数据从Ansi转换为Unicode。保存时遗留数据,发送网络数据等转换从Unicode为ANSI

+0

不知道为什么倒票。 Remy是对的:最好的行为是加载数据,转换为Unicode(系统的其余部分/ RTL/VCL/*所有*使用的),并在导出时转换回来。也就是说,将转化保留在应用程序的边缘。 –

相关问题