Уничтожение значений-объектов массива TMap из FCL-STL
Модератор: Модераторы
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
serbod, то, что вы назвали верно, но меня это как раз очень мало интересует. Для меня рекорды хороши тем, что не требуют освобождения памяти при удалении их из динамических массивов и перезагрузкой операторов. Поэтому, как я писал выше, если не требуется собственного поведения и наследования, то классы избыточны. А интерфейсы в тех же случаях - вообще стрельба из пушек по воробьям. То, что многие программисты выучив концепцию классов начинают совать их куда ни попадя, не есть хорошо.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
Снег Север писал(а): Для меня рекорды хороши тем, что не требуют освобождения памяти при удалении их из динамических массивов и перезагрузкой операторов.
Я бы не сказал, что это совсем уж так... записи, как переменные, прекрасно создаются и уничтожаются функциями New и Dispose. Конечно, это получаются ссылочные переменные, но тем не менее.Да и можно просто выделить под них несколько десятков байт. Фактически, с учетом того, что есть переменные-функции и переменные-процедуры, можно создать половину функционала полноценного объекта.
Снег Север писал(а):То, что многие программисты выучив концепцию классов начинают совать их куда ни попадя, не есть хорошо.
ППКС.
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
Возможно я неудачно выразился. Я имел ввиду, что если элемент массива - рекорд, то при удалении этого элемента нет нужды предварительно вызывать деструктор, как для классовых переменных.Лекс Айрин писал(а):Я бы не сказал, что это совсем уж так...
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
Снег Север, тут соглашусь.
serbod писал(а):Что будет, если Map[key] вернет nil? А оно обязательно будет.
Надо смотреть реализацию - вполне возможно что никогда и не вернет, но по хорошему конечно надо проверять.
serbod писал(а):Если не хочется заморачиваться с назначением владельца создаваемых объектов, то можно заморочиться с использованием интерфейсов вместо классов, они автоматически удаляются при отсутствии ссылок на них. Главная фишка - ссылка должна быть типа IInterface, а не TObject, иначе работать не будет.
Вот мне нужен массив 10e6 элементов содержащих некие координаты - x,y:byte - следуя вашим советам я получу огромный оверхед как по расходу памяти, так и по скорости исполнения. Не надо распространять принципы хорошо работающие с "большими" и "немногочислеными" структурами данных на всё подряд. Классы для больших структур, рекорд для мелких. Еще есть обжект - им можно организовать как "классовое" поведение, так и "рекордное"
java73
имеется ввиду ошибка
Код: Выделить всё
program Project1;
uses
gmap,gutil;
type
TMapElement = record
Key: string;
KeyType: string;
Value: string;
end;
less = specialize TLess<string>;
TTagsMap = specialize TMap<string, TMapElement, less>;
function TMapElement_Create(_key, _keytype, _value: string):TMapElement;
begin
result.Key:=_key;
result.KeyType:=_keytype;
result.Value:=_value;
end;
var
m:TTagsMap;
begin
m:=TTagsMap.Create;
m.Insert('1',TMapElement_Create('1','2','3'));
m.Insert('2',TMapElement_Create('1','2','3'));
m.Items['1'].Key:='23';
m.Destroy;
end. ?
TMap не предполагает такую стратегию использования. Items возвращает копию TMapElement из мапы.
Легко исправимо - напишите свой например MutableItems:PTValue возвращающий указатель или работайте через итераторы
Лекс Айрин
Обратите внимание на object`ы - имеют VMT при необходимости, есть наследование и могут быть созданы как в стеке, так и в куче
Добавлено спустя 3 минуты 10 секунд:
Снег Север
Я имел ввиду, что если элемент массива - рекорд, то при удалении этого элемента нет нужды предварительно вызывать деструктор, как для классовых переменных
Зависит от того что в этом рекорде лежит. Как только такая нужда появляется - рекорд желательно проапгрейдить до класса или обжекта
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
zub писал(а):Обратите внимание на object`ы - имеют VMT при необходимости, есть наследование и могут быть созданы как в стеке, так и в куче
Я о них помню. Это дублирование object/class мне столько крови попортило. В конце-концов, чисто для себя, признал object записью на "стероидах". Имхо, их наличие только портит "картину мира". Более того, по хорошему, лучше бы объединить record, object и class в одну конструкцию. А на этапе анализа программы разделять по наличию/отсутствию методов.
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
Не спорю, "как только, так сразу"...Лекс Айрин писал(а):Зависит от того что в этом рекорде лежит. Как только такая нужда появляется - рекорд желательно проапгрейдить до класса или обжекта
zub писал(а):Как только такая нужда появляется - рекорд желательно проапгрейдить до класса или обжекта
Курилка Север правильно говорит - все заняты Филькиным трудом, потому что нужды изначально нет. Но пример классный, я собственно ради него тут пишу чтобы, в случае надобности быстро найти:
zub писал(а):program Project1;
uses
gmap,gutil;
type
TMapElement = record
Key: string;
KeyType: string;
Value: string;
end;
less = specialize TLess<string>;
TTagsMap = specialize TMap<string, TMapElement, less>;
function TMapElement_Create(_key, _keytype, _value: string):TMapElement;
begin
result.Key:=_key;
result.KeyType:=_keytype;
result.Value:=_value;
end;
var
m:TTagsMap;
begin
m:=TTagsMap.Create;
m.Insert('1',TMapElement_Create('1','2','3'));
m.Insert('2',TMapElement_Create('1','2','3'));
m.Items['1'].Key:='23';
m.Destroy;
end.
Кстати Key: string; - лишний, как впрочем и KeyType: string;,
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
vitaly_l писал(а):Кстати Key: string; - лишний, как впрочем и KeyType: string;,
Не лишние. Например, это может быть элемент синтаксического дерева разбора. Там тогда и этого мало. Или просто графа (очереди, дерева,..). Да пусть даже и элемент БД (там в таблице идет триада имя/тип/значение)
Лекс Айрин писал(а):может быть
Речь об HTML парсере.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
vitaly_l, а HTML у нас уже не язык {разметки}?
Пример - плохой, тут нужен хешмап
Лекс Айрин писал(а):HTML у нас уже не язык {разметки}?
ТС же уже рассказал, что ему нужно всего лишь получить значения нескольких input из HTML. Уже второй месяц, весь форум ищет решение этой наисложнейшей задачи.
zub писал(а):Пример - плохой, тут нужен хешмап
zub - я впервые вижу столь скромного программиста. Да правильно, Вы правы! Хэш мап ускорит обработку втрое. Важно только найти наиболее быструю функцию хэширования. Например: md5 и Sha в одном хэшировании - максимально ускорят процесс поиска и разоблачения, input элементов в HTML парсерах. Ну и конечно, отсутствие HTML кода в программе, естественно замедлит её работу, т.к. элементы создаваемые прямо на форме, явно тормозят всю программу. А так примитивно - нормальные программисты не пишут! Нормальные пишут только через HTML ээээ хэширование
Последний раз редактировалось vitaly_l 01.04.2017 13:40:39, всего редактировалось 1 раз.
в продолжение плохих примеров
Добавлено спустя 2 минуты 3 секунды:
Nil - возвращается, не забываем - проверяем
Добавлено спустя 39 минут 8 секунд:
ну и по просьбам художников:
vitaly_l
С тебя сравнение скоростей и разработка суперхэшфункций
Код: Выделить всё
program Project1;
uses
gmap,gutil;
type
TMapElement = record
Key: string;
KeyType: string;
Value: string;
end;
less = specialize TLess<string>;
generic TMySuperPuperMap<TKey, TValue, TCompare> = class (specialize TMap<TKey, TValue, TCompare>)
function GetMutableItem(key:TKey):PTValue;inline;
end;
TTagsMap = specialize TMySuperPuperMap<string, TMapElement, less>;
function TMySuperPuperMap.GetMutableItem(key:TKey):PTValue;
var Pair:TPair; ret:TIterator;
begin
Pair.Key:=key;
result:=pointer(FSet.NFind(Pair));
if result<>nil then
begin
result:=@(TMSet.PNode(result)^.data);
if result<>nil then
result:=@(PTPair(result)^.Value);
end;
end;
function TMapElement_Create(_key, _keytype, _value: string):TMapElement;
begin
result.Key:=_key;
result.KeyType:=_keytype;
result.Value:=_value;
end;
var
m:TTagsMap;
begin
m:=TTagsMap.Create;
m.Insert('1',TMapElement_Create('1','2','3'));
m.Insert('2',TMapElement_Create('1','2','3'));
m.GetMutableItem('1')^.Key:='23';
m.Destroy;
end. Добавлено спустя 2 минуты 3 секунды:
Nil - возвращается, не забываем - проверяем
Добавлено спустя 39 минут 8 секунд:
ну и по просьбам художников:
Код: Выделить всё
program Project1;
uses
ghashmap,gutil;
type
TMapElement = record
Key: string;
KeyType: string;
Value: string;
end;
MyStringHash=class
class function hash(s:AnsiString; n:longint):SizeUInt;
end;
generic TMySuperPuperHashMap<TKey, TValue, Thash> = class (specialize THashMap<TKey, TValue, Thash>)
function GetMutableItem(key:TKey):TIterator.PValue;inline;
end;
TTagsMap = specialize TMySuperPuperHashMap<string, TMapElement, MyStringHash>;
function MakeHash(const s:AnsiString):SizeUInt;
var
I: Integer;
begin
Result := 0;
for I := 1 to Length(s) do
Result := ((Result shl 7) or (Result shr 25)) + Ord(s[I]);
end;
class function MyStringHash.hash(s:AnsiString; n:longint):SizeUInt;
begin
result:=makehash(s) mod SizeUInt(n);
end;
function TMySuperPuperHashMap.GetMutableItem(key:TKey):TIterator.PValue;
var i,bs:SizeUInt;
curbucket:TContainer;
begin
curbucket:=FData[THash.hash(key,FData.size)];
bs:=curbucket.size;
i:=0;
while i < bs do begin
if (curbucket[i].Key = key) then exit(@curbucket.Mutable[i]^.Value);
inc(i);
end;
// exception?
end;
function TMapElement_Create(_key, _keytype, _value: string):TMapElement;
begin
result.Key:=_key;
result.KeyType:=_keytype;
result.Value:=_value;
end;
var
m:TTagsMap;
PElement:^TMapElement;
begin
m:=TTagsMap.Create;
m.Insert('1',TMapElement_Create('1','2','3'));
m.Insert('2',TMapElement_Create('4','5','6'));
PElement:=m.GetMutableItem('1');
if PElement<>nil then
PElement^.Key:='23';
m.GetMutableItem('2')^.Key:='23';
m.Destroy;
end. vitaly_l
С тебя сравнение скоростей и разработка суперхэшфункций
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
vitaly_l писал(а):ТС же уже рассказал, что ему нужно всего лишь получить значения нескольких input из HTML.
И чё? Это ничего не меняет. Для того чтобы их получить, надо знать где и для чего они используются. А для этого требуется разбор, по крайней мере, тегов где они встречаются.
vitaly_l писал(а):Уже второй месяц, весь форум ищет решение этой наисложнейшей задачи.
Возможно, потому что не там ищут. Есть шанс, что в тексте страницы этих значений нет (или УЖЕ нет), так как они отправляются на сервер, который обновляет динамически страницу. Т. е. в этом случае надо теребить запрос.
Я уже не помню всю технологию, так как давно не занимался. Но там логика работы немного вывернута наизнанку.
