喫茶XRAYトップページ

[スレッド全体
]

[7276] StringList ソートの速さ比べ返信 削除
2014/2/28 (金) 16:57:19 taki
StringListに逐次データが追加される場合、追加の度にsortメソッドを実行するより
最初から Sorted := true; にする方が断然速いようです。

※私のPCの環境では…

// 追加後Sort  1,267ms 1,000回 (※10,000回だとなかなか帰ってこない)
  for i := 1 to 1000 do begin
    sl.Append(FormatCurr('000000',Random(1000000)));
    sl.Sort;
  end;

// 初めからTrue 77ms 10,000回
  sl.Sorted := true;
  for i := 1 to 10000 do begin
    sl.Append(FormatCurr('000000',Random(1000000)));
  end;

// ちなみに 追加のみ 5ms 10,000回
  sl.Sorted := false;
  for i := 1 to 10000 do begin
    sl.Append(FormatCurr('000000',Random(1000000)));
  end;

データを最後に追加してから並べ替えるより、データを突っ込むところを探して
追加する方が速いのでしょうね。たぶん。



[7298] Re:StringList ソートの速さ比べ返信 削除
2014/3/4 (火) 10:08:28 おかぽん
こんにちは。

StringListでソートとなると、どうしても文字列のソートになってしまうから、
あまり使わないので、自分の使う方法。

StringGridで表示する場合、大抵別のクラスで行ごとのデータを持っているから

THoge=class
  Col1: String;
  Col2:Integer;
  Col3:TDateTime;
end;

とか宣言し、TClassListに全データ入れてしまう。

そして、StringGridへの初回表示は、以下のようにObjectsを使って、行と実データを
関連付けしてしまう。

var
  i: Integer;
begin
  //行数確保
  StringGrid.RowCount :=  ClassList.Count + 1;
  //0列にクラス参照設定
  for i := 1 to  StringGrid.RowCount -1 do
  begin
    StringGrid.Objects[0,i] := ClassList.Items[i-1];
    RowUpdate(i);
  end;
end;

各セルへの更新は 関連付けされたデータを参照して行う
procedure TForm1.RowUpdate(aRow: Integer);
var
  hoge: THoge;
begin
  hoge := StringGrid.Objects[0,aRow];
  StringGrid.Cells[0, aRow] := hoge.Col1;
  StringGrid.Cells[1, aRow] := IntToStr(hoge.Col2);
  StringGrid.Cells[2, aRow] := FormatDateTime('yyyy/mm/dd', hoge.Col3);
end;

ソートは、StringList.CustomSort()を使う。

function StringListSortCompareA(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := AnsiCompareString(THoge(List.Objects[Index1]).Col1,
     THoge(List.Objects[Index1]).Col2);
end;
function StringListSortCompareB(List: TStringList; Index1, Index2: Integer): Integer;
begin
  //
end;

var
  stringList: TStringList;
  i: Integer;
begin
  stringList := TStringList.Create;
  stringList.Assign(StringGrid.Cols[0]);
  StringList.CustomSort(StringListSortCompareA);
  StringGrid.Cols[0].Assign(stringList);
   for i := 1 to  StringGrid.RowCount -1 do RowUpdate(i);
  stringList.Free;
end;

TStringListSortCompareを使い、1対1の比較関数を作るので、複数列をキーに並び替えできる。
別途作成した機能で、THogeの内容を更新しても、RowUpdate関数で、内容を反映できる。

個別の比較関数が必要になるので、汎用的ではありませんけど。

[▼次のスレッド]
INCM/CMT
Cyclamen v3.82