При использовании Delphi 2009 эта операция приблизительно в 3 раза быстрее с TStringBuilder, чем с ReplaceString. Это - безопасный Unicode, также.
Я использовал текст из http://www.CodeGear.com со всеми случаями" <" и">" измененный на "<"
и ">"
как моя начальная точка.
Включая строковые присвоения и создающие/освобождающие объекты, они взяли приблизительно 25 мс и 75 мс соответственно в моей системе:
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), и 'победитель' был в 14 раз быстрее, чем Delphi RTL.
Несколько из функций fastcode были включены в самом Delphi в последних версиях (D2007 на, я думаю), таким образом, повышение производительности может варьироваться существенно, в зависимости от которой версии Delphi Вы используете.
Как упомянуто прежде, необходимо действительно смотреть на основанное на Unicode решение, если Вы серьезно относитесь к обработке XML.
Проблема состоит в том, что Вы выполняете итерации всего размера строки дважды (один для замены >> и другой для замены < <).
Необходимо выполнить итерации с для и просто проверить вперед каждый раз, когда Вы находите a и для gt; или лейтенант; и сделайте непосредственную замену и затем пропуск 3 символов ((g|l) t;). Таким образом, это может сделать это в пропорциональное время к размеру строки xml. Текст.
Простой пример C#, поскольку я не знаю Delphi, но должен сделать, чтобы Вы в общих чертах поняли.
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>
Непротестированное преобразование кода C# записано Jorge Ferreira.
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;
Systools (Turbopower, теперь открытый исходный код) сделал, чтобы ReplaceStringAllL функционировал, который делает всех их в строке.