我使用StringReplace替換& GT和& LT由焦炭本身在生成的XML是這樣的:StringReplace的替代品,以提高性能
StringReplace(xml.Text,'>','>',[rfReplaceAll]) ;
StringReplace(xml.Text,'<','<',[rfReplaceAll]) ;
的事情是它需要的方式tooo長替換的每一次出現& gt。
你有什麼更好的主意讓它更快嗎?
我使用StringReplace替換& GT和& LT由焦炭本身在生成的XML是這樣的:StringReplace的替代品,以提高性能
StringReplace(xml.Text,'>','>',[rfReplaceAll]) ;
StringReplace(xml.Text,'<','<',[rfReplaceAll]) ;
的事情是它需要的方式tooo長替換的每一次出現& gt。
你有什麼更好的主意讓它更快嗎?
嘗試從彼得莫里斯FastStrings.pas。
的問題是,你迭代整個字符串大小的兩倍(一個用於替換& GT;可以通過>和另一個替換& lt;通過<)。
你應該迭代一個for,只要你找到一個&就可以檢查一下GT;或lt;並立即替換,然後跳過3個字符((g | l)t;)。通過這種方式,它可以在比例的時間內對字符串xml.Text的大小進行處理。
一個簡單的C#示例,因爲我不知道德爾福,但應該爲你做的一般想法。
String s = "<xml>test</xml>";
char[] input = s.ToCharArray();
char[] res = new char[s.Length];
int j = 0;
for (int i = 0, count = input.Length; i < count; ++i)
{
if (input[i] == '&')
{
if (i < count - 3)
{
if (input[i + 1] == 'l' || input[i + 1] == 'g')
{
if (input[i + 2] == 't' && input[i + 3] == ';')
{
res[j++] = input[i + 1] == 'l' ? '<' : '>';
i += 3;
continue;
}
}
}
}
res[j++] = input[i];
}
Console.WriteLine(new string(res, 0, j));
此輸出:
<xml>test</xml>
問題不是迭代字符串兩次,而是讓它處理許多替換。對於不同的字符串,調用它兩次或更多是沒有問題的,如果實現它與RTL中的方式不同,則替換它。 – 2011-09-08 19:22:31
由豪費雷拉寫入的C#代碼的未測試的轉換。
function ReplaceLtGt(const s: string): string;
var
inPtr, outPtr: integer;
begin
SetLength(Result, Length(s));
inPtr := 1;
outPtr := 1;
while inPtr <= Length(s) do begin
if (s[inPtr] = '&') and ((inPtr + 3) <= Length(s)) and
(s[inPtr+1] in ['l', 'g']) and (s[inPtr+2] = 't') and
(s[inPtr+3] = ';') then
begin
if s[inPtr+1] = 'l' then
Result[outPtr] := '<'
else
Result[outPtr] := '>';
Inc(inPtr, 3);
end
else begin
Result[outPtr] := Result[inPtr];
Inc(inPtr);
end;
Inc(outPtr);
end;
SetLength(Result, outPtr - 1);
end;
這是保存爲Unicode嗎? – 2008-09-26 16:56:46
Systools(Turbopower,現在開源)有一個ReplaceStringAllL函數,它可以在字符串中執行所有這些函數。
如果您使用的是Delphi 2009,那麼使用TStringBuilder比使用ReplaceString快3倍。它也是Unicode安全的。
我使用的文本從http://www.CodeGear.com與變更爲"<"
和">"
作爲我的出發點的「<」和「>」所有事件。
包括字符串,分配和創建/釋放的對象,這些花費了大約25毫秒和75ms分別在我的系統:
function TForm1.TestStringBuilder(const aString: string): string;
var
sb: TStringBuilder;
begin
StartTimer;
sb := TStringBuilder.Create;
sb.Append(aString);
sb.Replace('>', '>');
sb.Replace('<', '<');
Result := sb.ToString();
FreeAndNil(sb);
StopTimer;
end;
function TForm1.TestStringReplace(const aString: string): string;
begin
StartTimer;
Result := StringReplace(aString,'>','>',[rfReplaceAll]) ;
Result := StringReplace(Result,'<','<',[rfReplaceAll]) ;
StopTimer;
end;
你一定要看看Fastcode項目網頁:http://fastcode.sourceforge.net/
他們跑了挑戰爲了更快的StringReplace(Ansi StringReplace挑戰),「贏家」比Delphi RTL快14倍。
幾個fastcode函數已經包含在Delphi本身的最新版本中(我認爲D2007),所以根據你使用的是哪個Delphi版本,性能改進可能會有很大的不同。
如前所述,如果您認真對待處理XML,您應該真的在尋找基於Unicode的解決方案。
當您處理多行文本文件時,您可以通過逐行處理獲得一些性能。在我的測試中,這種方法將大約90%的時間減少到大於1MB xml文件的進程替換。
procedure ReplaceMultilineString(xml: TStrings);
var
i: Integer;
line: String;
begin
for i:=0 to xml.Count-1 do
begin
line := xml[i];
line := StringReplace(line, '>', '>', [rfReplaceAll]);
line := StringReplace(line, '<', '<', [rfReplaceAll]);
xml[i] := line;
end;
end;
注:德爾福10西雅圖。
你可以得到任何關於原始代碼Spul vs. Jorge的代碼與FastStrings的反饋嗎? – gabr 2008-09-27 06:49:01
StringReplace的問題是當您有多個需要替換的事件時。在這種情況下,你應該編寫自己的版本,類似於Gabr發佈的版本。實際上這個問題不是調用StringReplace 2次,而是讓它處理幾十個替換。 – 2011-09-08 19:20:48