Форум: "Начинающим";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];
ВнизЗапись большого количества однотипных данных в Stream. Найти похожие ветки
← →
Riply © (2006-11-22 08:28) [0]Здравствуйте !
Если мне надо, например, сохранить TStrings вместе с
объектами, то я делаю так:
procedure TObjStrings.SaveObjToStream(Stream: TStream);
var
i: integer;
cbData: DWord;
S: string;
begin
S:= GetTextStr;
cbData:= Length(S);
Stream.Size:= Stream.Size + cbData + (Count + 1) * SizeOf(DWord);
Stream.Write(cbData, SizeOf(DWord));
if cbData > 0 then Stream.Write(S[1], cbData);
for i:=0 to Count - 1 do
begin
cbData:= DWord(Objects[i]);
Stream.Write(cbData, SizeOf(DWord));
end;
end;
Если много строк, то изменение Stream.Size заметно ускоряет процесс.
Но, если при сохранении коллекции поступаю похожим
образом, то скорость падает.
Коллекцию сохраняю используя перебор всех published
type
TSuperPuperItem = class(TCollectionItem)
private
FList: TStringList;
published
.....// Много св- в.
property MyList: TStringList read FList write FList;
.....
end;
type
TSuperPuperCollection = class(TOwnedCollection)
public
procedure StreamSavePreparation(Stream: TStream); virtual;
end;
procedure TSuperPuperCollection.StreamSavePreparation(Stream: TStream);
var
i: integer;
CommSize: Int64;
begin
CommSize:= 0;
for i:= 0 to Count - 1 do
with Items[i] do CommSize:= CommSize + Length(FList.Text);
Stream.Size:= Stream.Size + CommSize + (Count + 1) * SizeOf(DWord);
end;
При использовании StreamSavePreparation скорость получается ниже,
чем при индивдуальной поправке Stream.Size для каждого Item.
В чем может быть дело ?
P.S. Измерения произвожу при помощи GetTickCount, т.к. другого способа, пока, не знаю :(
← →
Сергей М. © (2006-11-22 08:45) [1]
> В чем может быть дело ?
Вот в этом
> for i:= 0 to Count - 1 do
> with Items[i] do CommSize:= CommSize + Length(FList.Text);
А вообще нет смысла вычислять будущий размер стрима заранее.
← →
Riply © (2006-11-22 11:58) [2]Спасибо ! Когда носом ткнут, все сразу становиться таким очевидным ! :)
А почему "нет смысла вычислять будущий размер стрима заранее" ?
← →
Anatoly Podgoretsky © (2006-11-22 12:03) [3]> Riply (22.11.2006 11:58:02) [2]
Смысл есть если ты его знаешь.
← →
Сергей М. © (2006-11-22 12:04) [4]
> А почему
Потому что метод TStream.Write[Buffer] сам по себе наращивает размер стрима на необходимую величину.
← →
Сергей М. © (2006-11-22 12:12) [5]
> Riply © (22.11.06 08:28)
И вообще заставлять объект-коллекцию сохранять в поток свои объекты-элементы не есть корошо.
В общем случае лучше сделать так:
TMyCollectionItem = class(TCollectionItem)
..
procedure SaveToStream(AStream: TStream);
..
end;
...
for i := 0 to Count - 1 do
Items[i].SaveToStream(SomeStream);
← →
Riply © (2006-11-22 12:43) [6]> [4] Сергей М. © (22.11.06 12:04)
"Потому что метод TStream.Write[Buffer] сам по себе наращивает размер стрима на необходимую величину"
Но, как мне кажется, не есть хорошо, снова и снова добавлять память кусочками.
Лучше сразу сказать сколько тебе надо :)
Да и пример на проверку скорости :
procedure TMainForm.SpeedButton3Click(Sender: TObject);
const
aCount = 10000000;
var
i, Tm: integer;
Strm: TMemoryStream;
begin
Strm:= TMemoryStream.Create;
try
Tm:= GetTickCount;
// Strm.Size:= Strm.Size + aCount * SizeOf(DWord);
for i:= 0 to Pred(aCount) do Strm.Write(i, SizeOf(DWord));
ShowMessage(IntToStr(GetTickCount - Tm));
finally
Strm.Free;
end;
end;
В зависимости от наличия закомментированной строчки возвращает 172 и 469
Т. е. в 2.5 раза быстрее.
← →
Riply © (2006-11-22 12:54) [7]>Сергей М. © (22.11.06 12:12)
>И вообще заставлять объект-коллекцию сохранять в поток свои объекты-элементы не есть корошо.
Поностью согласна. Просто это у меня плавно стало перерождаться из
общей процедуры сохранения published св-в объекта в поток.
Решила, что если для коллекций индивидуальный способ сохранения,
то почему бы и не расширить его :)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.041 c