0

アプリで頻繁に呼び出される関数があります。これは基本的にcsvパーサーであり、最初の値を「ポップ」し、入力文字列を残りの文字列に変更します。

function StripString(mask: string; var modifiedstring: string): string;
var
  index,len: integer;
  s: string;
begin
    Index := pos(Mask, ModifiedString);
    len := Length(ModifiedString);
    if index <> 0 then
    begin
        if Index <> 1 then
        begin
            s := LeftStr(ModifiedString, index - 1);
            ModifiedString := RightStr(ModifiedString, len-index);
        end else begin
            if Length(ModifiedString)>1 then
              ModifiedString := Copy(ModifiedString,2,len)
            else
              ModifiedString := '';
            s := '';
        end;
    end else begin
        s := ModifiedString;
        ModifiedString := '';
    end;
    result := s
end;

PChars を使用して、このルーチンを最適化してみたいと思います。だから私はこの方法を思いつきましたが、残念ながら結果の出力に奇妙な文字が表示されます。間違ったポインタが原因だと推測しています。

//faster method - uses PChars
function StripStringEx(mask: char; var modifiedstring: string): string;
var
  pSt,pCur,pEnd : Pchar;
begin
    pEnd := @modifiedString[Length(modifiedString)];
    pSt := @modifiedString[1];
    pCur := pSt;
    while pCur <= pEnd do
    begin
         if pCur^ = mask then break;
         inc(pCur);
    end;
    SetString(Result,pSt,pCur-pSt);
    SetString(ModifiedString,pCur+1,pEnd-pCur);
end;

誰でも「ポイント」:)私を正しい方向に向けますか?

4

2 に答える 2

3

ポインターのバージョンが動作するようになったとしても、なぜ高速になるのかわかりません。

適度に最適化されているため、呼び出しPosはループよりも高速です。Pos割り当てパターンは、2 つのヒープ割り当てとヒープ割り当て解除の両方のバージョンで同じです。私は動作するバージョンに固執します。

ローカル変数を取り除き、s直接割り当ててResult、参照カウントを少しスキップできます。

于 2011-04-19T08:31:33.027 に答える
1

ModifiedStringのSetStringが原因で、奇妙な結果が得られると思います。SetStringは、最初に文字列の長さを設定し、次にコンテンツをバッファから新しく作成された文字列にコピーします。しかし、あなたの場合、バッファが宛先であり、バッファの長さが調整されたばかりです。

Davidのアドバイスに従ってください。PCharは使用しないでください。

必要に応じて、少し短くすることができます。

function StripString(const Mask: string; var ModifiedString: string): string;
var
  Index: Integer;
begin
  Index := Pos(Mask, ModifiedString);
  if Index <> 0 then
  begin
    Result := LeftStr(ModifiedString, Index - 1);
    Delete(ModifiedString, Index);
  end
  else
  begin
    Result := ModifiedString;
    ModifiedString := '';  
  end;
end;
于 2011-04-19T18:53:25.243 に答える