Текущий архив: 2007.03.18;
Скачать: CL | DM;
Вниз
Копируется ли строка про добавлении в ListBox или нет ? Найти похожие ветки
← →
Альф (2007-01-24 10:43) [0]Есть массив строк
var
astr: array of string;
необходимо это массив визуализировать - например вывести в ListBox.
Вопрос - будет ли дублироваться в памяти каждая строка при добавлении из массива строк в ListBox.Items ?
Или же физически строка в памяти будет одна - а в ListBox.Items будет только ссылка на неё ?
← →
Rouse_ © (2007-01-24 10:45) [1]Будет дублироваться...
← →
TRUNK © (2007-01-24 11:01) [2]По идее для строк применяется правило CopyOnWrite, т.е. при простом копировании строки происходит только копирование указателя, а уже при попытке изменения скопированной строки происходит создание второй строки с другим указателем.
← →
Игорь Шевченко © (2007-01-24 11:20) [3]Rouse_ © (24.01.07 10:45) [1]
Не будет дублироваться
← →
Rouse_ © (2007-01-24 11:58) [4]
> Не будет дублироваться
Да? Хм...function TListBoxStrings.Add(const S: string): Integer;
begin
Result := -1;
if ListBox.Style in [lbVirtual, lbVirtualOwnerDraw] then exit;
Result := SendMessage(ListBox.Handle, LB_ADDSTRING, 0, Longint(PChar(S)));
if Result < 0 then raise EOutOfResources.Create(SInsertLineError);
end;
Проверка:procedure TForm24.Button1Click(Sender: TObject);
var
i: integer;
S, A, B, C: String;
begin
S := "Просто достточно длинная строка символов для проверки алгоритмя работы" + IntToStr(GetTickCount);
for i := 0 to 3000 do
ListBox1.Items.Add(S);
A := S;
B := S;
C := S;
ShowMessage(IntToStr(DWORD(Pointer(DWORD(Pointer(S)) - 8)^)));
end;
Что и требовалось доказать :)
← →
Игорь Шевченко © (2007-01-24 12:38) [5]Rouse_ © (24.01.07 11:58) [4]
А ты подумай, с чего ей дублироваться ?
← →
clickmaker © (2007-01-24 12:43) [6]
> [4] Rouse_ © (24.01.07 11:58)
lParam
Pointer to the null-terminated string that is to be added.
If you create the list box with an owner-drawn style but without the LBS_HASSTRINGS style, this parameter is stored as item data instead of the string to which it would otherwise point
указатель это. Откуда там возьмется дубль?
← →
clickmaker © (2007-01-24 12:52) [7]хотя...
LBS_HASSTRINGS
Specifies that a list box contains items consisting of strings. The list box maintains the memory and addresses for the strings
то есть, он копирует строки к себе?
тогда дубль, да
← →
Rouse_ © (2007-01-24 13:09) [8]
> А ты подумай, с чего ей дублироваться ?
> то есть, он копирует строки к себе?
Да копирует, для оптимизации добавления большого кол-ва строк есть даже сообщение LB_INITSTORAGE
← →
Rouse_ © (2007-01-24 13:14) [9]Проверка №2, для неверующих:
procedure TForm24.Button1Click(Sender: TObject);
var
i, d: integer;
S: String;
begin
S := "Просто достточно длинная строка символов для проверки алгоритмя работы" + IntToStr(GetTickCount);
for i := 0 to 3000 do
ListBox1.Items.Add(S);
d := 32;
for i := 0 to 69 do
Move(d, Pointer(DWORD(Pointer(S)) + I)^, 1);
ShowMessage(S);
S := ListBox1.Items.Strings[1];
ShowMessage(S);
end;
← →
Rouse_ © (2007-01-24 13:16) [10]Даже вот так лучше и наглядней:
procedure TForm24.Button1Click(Sender: TObject);
var
i, d: integer;
S, A: String;
begin
S := "Просто достточно длинная строка символов для проверки алгоритмя работы" + IntToStr(GetTickCount);
for i := 0 to 3000 do
ListBox1.Items.Add(S);
d := 32;
A := S;
for i := 0 to 69 do
Move(d, Pointer(DWORD(Pointer(S)) + I)^, 1);
ShowMessage(S);
ShowMessage(A);
S := ListBox1.Items.Strings[1];
ShowMessage(S);
end;
← →
Игорь Шевченко © (2007-01-24 13:37) [11]Rouse_ © (24.01.07 13:16) [10]
А чего твой код-то показывает ?
← →
Rouse_ © (2007-01-24 13:40) [12]1. добавляем строки в ListBox
2. присваиваем строку другой переменной (в этот момент они указывают на один и тот же буффер)
3. пишем в этот буффер пробелы, чтобы небыло вызова UniqueStr
4. проверяем - обе переменных читающие с этого буффера показывают наличие пробелов
5. еслибы в listBox были тоже указатели, то последний ShowMessage(S) показал бытоже, что и ShowMessage(A)
6. А показывается полная строка.
7. вопрос, откуда берется эта полная оригинальная строка, если буффер. который ее хранил затерт пробелами...?
← →
Игорь Шевченко © (2007-01-24 13:52) [13]Rouse_ © (24.01.07 13:40) [12]
Теперь попробоуй свой код с ListBox, у которого стиль позволяет хранить пользовательские строки. Интересно.
← →
Rouse_ © (2007-01-24 13:56) [14]Вот если стиль стоит lbVirtual у listBox, тогда все нормально все три ShowMessage показывают наличие пробелов. По умолчанию же стоит стиль lbStandard, который именно копирует
← →
Альф (2007-01-24 15:05) [15]Большое спасибо всем кто учавствовал в обсуждении.
Сделал небольшой пример, на котором видно что памяти используется гораздо больше чем нужно было бы.
Шаг 1:
Запускаем програмку.
Размер виртуальной памяти процесса в диспетчере задач = 848К
Шаг 2:
Вызываем эту процедуру - размер памяти = 7 240К
var
astr: array of string;
procedure T_main.Button5Click(Sender: TObject);
const
S_1 = " - Просто досточно длинная строка символов для проверки алгоритма работы";
var
i: integer;
begin
Button5.Enabled := false;
SetLength(astr, High(word));
for i := Low(astr) to High(astr) do begin
astr[i] := IntToStr(i) + S_1 + IntToStr(Random(i));
end;
Sleep(500);
Button5.Enabled := true;
end;
Проверяем на калькуляторе примерный размер: 90*65534 = около 6М.
Не точно - но очень похоже.
Шаг 2:
Заполняем ListBox1.
Процедура выполняется достаточно долго - результирующий размер памяти = 19 860К :(
Прирост еще в 12М ??? Судя по всему - или добавляется две копии - или же все строки переводяться в Unicode.
procedure T_main.Button6Click(Sender: TObject);
var
i: integer;
begin
Button6.Enabled := false;
ListBox1.Items.BeginUpdate();
for i := Low(astr) to High(astr) do begin
ListBox1.Items.Add(astr[i]);
end;
ListBox1.Items.EndUpdate();
Sleep(500);
Button6.Enabled := true;
end;
Еще раз повторюсь - процедура работает в несколько раз дольше чем первая.
Шаг 3:
Чистим ListBox
ListBox1.Clear();
Размер виртуалки практически возвратился к исходному и = 7 304К
← →
Игорь Шевченко © (2007-01-24 17:35) [16]Альф (24.01.07 15:05) [15]
Разумеется, строки переводятся в Unicode, если ListBox их хранит
Но зачем отображать в listBox 65 тысяч строк в стандартном режиме - мания такая, да ? Пусть нашим пользователям будет хуже ?
Страницы: 1 вся ветка
Текущий архив: 2007.03.18;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.037 c