powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Обновление словаря
25 сообщений из 36, страница 1 из 2
Обновление словаря
    #40081838
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть у меня закешированный список. В какой-то момент мне этот список нужно обновить реальными значениями и каждому элементу списка присвоить статус:
Если элемент был в кеше и остался - wnNothing
Если элемент был в кеше и пропал - wnUnregister
Если элемент появился в кеше - wnRegister

Идея была следующая:
всем существующим элементам в кеше присваиваем wnUnregister
далее идем по реальному списку и смотрим состояние кеша. Если элемент есть в кеше, то меняем его состояние на wnNothing, в противном случае, добавляем его со статусом wnRegister
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
procedure RefreshWriters(AWriters: TDictionary<TSharedHandle, TWriterNotify>);
var
  LWriter: TSharedHandle;
  Li: Integer;
begin
    for LWriter in AWriters.Keys do
      AWriters[LWriter] := wnUnregister;

    for Li := 0 to GetWriterCount - 1 do begin
      LWriter := GetWriterHandle(Li);
      if AWriters.ContainsKey(LWriter) then
        AWriters[LWriter] := wnNothing
      else
        AWriters.Add(LWriter, wnRegister);
    end;
end;

в этом коде меня смущает постоянный поиск элемента по вычисляемому хешу. Никак нельзя его оптимизировать?

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Обновление словаря
    #40081842
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Оно и так О(1), можно разве что не делать это дважды.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обновление словаря
    #40081847
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
можно разве что не делать это дважды.
Что можно убрать?
...
Рейтинг: 0 / 0
Обновление словаря
    #40081848
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вместо ContainsKey использовать что-то, что сразу возвращает указатель на TWriterNotify в
случае успеха.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обновление словаря
    #40081854
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Вместо ContainsKey использовать что-то, что сразу возвращает указатель на TWriterNotify в случае успеха.
Ну это было бы просто. Но стандартный TDictionary так не умеет
...
Рейтинг: 0 / 0
Обновление словаря
    #40081864
swame2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

_Vasilisk_,

Вызывать TryAdd , если выдало false - то уже присвоение wnNothing.
...
Рейтинг: 0 / 0
Обновление словаря
    #40081877
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Ну это было бы просто. Но стандартный TDictionary так не умеет

Не верю. Загляни ему в исподники ContainsKey().
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обновление словаря
    #40081896
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
swame2
Вызывать TryAdd
Нет такого. Есть либо AddOrSet без статуса о том, что сделали, либо Add и ловить исключение
Тынц
Write
MethodIndex type Value type If duplicate keyAddTKeyTValueExceptionAddOrSetValueTKeyTValueOverwriteItemsTKeyTValueOverwrite
Read
MethodIndex/input type Result typeIf key not foundNotesContainsKeyTKeyBooleanfalseTrue = foundContainsValueTValueBooleann/aTrue = foundExtractPairTKeyTPairDefault pairReturns TPair, removes item from dictionaryItemsTKeyTValueExceptionUse TryGetValue to avoid exceptionoperator []TKeyTValueExceptionC++ onlyKeysn/aTKeyCollectionn/aToArrayn/aTArray<TPair<TKey,TValue>>n/aTryGetValueTKeyTValue, Booleandefault, falseReturns TValueValuesn/aTValueCollectionn/a
Dimitry Sibiryakov
Не верю. Загляни ему в исподники ContainsKey().
Там все приватное. И массив значений и функции вычисления хеша
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
  TDictionary<TKey,TValue> = class(TEnumerable<TPair<TKey,TValue>>)
  private type
    TItem = record
      HashCode: Integer;
      Key: TKey;
      Value: TValue;
    end;
    TItemArray = array of TItem;
  private
    FItems: TItemArray;
    FCount: Integer;
    function GetBucketIndex(const Key: TKey; HashCode: Integer): Integer;
    function Hash(const Key: TKey): Integer;
..........
function TDictionary<TKey,TValue>.ContainsKey(const Key: TKey): Boolean;
begin
  Result := GetBucketIndex(Key, Hash(Key)) >= 0;
end;
...
Рейтинг: 0 / 0
Обновление словаря
    #40081899
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
del
...
Рейтинг: 0 / 0
Обновление словаря
    #40081900
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_TryGetValue TKey TValue, Boolean default, false Returns TValue

Вот оно. Ты получаешь или указатель на значение или флаг, что его нет, за одну операцию.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обновление словаря
    #40081902
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Ты получаешь или указатель на значение
Нет. Я получаю само значение по ссылке
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
function TDictionary<TKey,TValue>.TryGetValue(const Key: TKey; out Value: TValue): Boolean;
var
  index: Integer;
begin
  index := GetBucketIndex(Key, Hash(Key));
  Result := index >= 0;
  if Result then
    Value := FItems[index].Value
  else
    Value := Default(TValue);
end;
...
Рейтинг: 0 / 0
Обновление словаря
    #40081913
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
в этом коде меня смущает постоянный поиск элемента по вычисляемому хешу. Никак нельзя его оптимизировать?

_Vasilisk_,

я в этих новых дельфях не разбираюсь, но вот в C++ есть контейнер "двухвостая "очередь", std::deque<>. Так вот, у нее, кроме мгновенной вставки/удаления в оба хвоста, также реализованная сложность доступа про индексу == O(1), т.е. как у массива/вектора.

Может, и в новых дельфях такое есть?
...
Рейтинг: 0 / 0
Обновление словаря
    #40081919
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Я получаю само значение по ссылке

Да пофиг, в Дельфи это и есть указатель. Оно-то тебе и надо чтобы установить в него wnNothing.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обновление словаря
    #40081929
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Да пофиг, в Дельфи это и есть указатель.
Нет. Не пофиг. Значение в методе копируется в переданный указатель. По сути мне нужен указатель на указатель
ъъъъъ
также реализованная сложность доступа про индексу
А ничего, что у меня не последовательный индекс, а структура?
...
Рейтинг: 0 / 0
Обновление словаря
    #40081942
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
Код: pascal
1.
2.
    for LWriter in AWriters.Keys do
      AWriters[LWriter] := wnUnregister;


Это странный код. Проход по списку ключей, и в каждой итерации - снова доступ к элементу по ключу.
Нельзя ли сразу выполнить проход по списку значений, получая в for ссылку на элемент?
В D2007 нельзя, но может, в новых дельфях можно? Вот, как в новых C++:
Код: plaintext
1.
2.
for (auto & itm : container)
  itm = ...
...
Рейтинг: 0 / 0
Обновление словаря
    #40081945
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
Нельзя ли сразу выполнить проход по списку значений
Нет
ъъъъъ
получая в for ссылку на элемент?
Нет
...
Рейтинг: 0 / 0
Обновление словаря
    #40081970
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Ну если тебе прям очень надо - возьми rtti.
...
Рейтинг: 0 / 0
Обновление словаря
    #40081991
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ

Нельзя ли сразу выполнить проход по списку значений, получая в for ссылку на элемент?


Код: pascal
1.
    for ObjectData in fAllObjectsContainer.Values do



но возможно ObjectData будет ридонли, не могу сейчас в дельфах глянуть.
...
Рейтинг: 0 / 0
Обновление словаря
    #40082064
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0r
возможно ObjectData будет ридонли,
Будет
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
      TValueEnumerator = class(TEnumerator<TValue>)
      private
        FDictionary: TDictionary<TKey,TValue>;
        FIndex: Integer;
        function GetCurrent: TValue;
      protected
        function DoGetCurrent: TValue; override;
        function DoMoveNext: Boolean; override;
      public
        constructor Create(const ADictionary: TDictionary<TKey,TValue>);
        property Current: TValue read GetCurrent;
        function MoveNext: Boolean;
      end;
...
Рейтинг: 0 / 0
Обновление словаря
    #40082066
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Ну если тебе прям очень надо
Тут скорее был вопрос: может я чего не вижу?
...
Рейтинг: 0 / 0
Обновление словаря
    #40082127
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Тут скорее был вопрос: может я чего не вижу?

Публичный интерфейс словаря не предоставляет нужной тебе функциональности. Поэтому, если оптимизировать доступ хочется не из любви в искусству, то остаётся только rtti.
...
Рейтинг: 0 / 0
Обновление словаря
    #40082132
swame2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

Поверхностно тут сильно не соптимизируешь. TDictionary не особо рассчитан на такие последовательны проходы по циклу как в 1 цикле.

Тут нужно
1. Понять действительно ли нужно выжимать эту оптимизацию.

если нужно то варианты
1. написать наследник или хелпер к TDictionary с прямых проходом по FItems
2. раскидать айтемы с разными статусами по разным TDictionary.
Нужно знать насколько часто происходит чтение и запись статусов, что нужно в первую очередь быстрее.
3. Знать какая природа у TSharedHandle. Может они идут подряд или почти и можно их положить в массив.
4. использовать другие реализации TDictionary (я знаю варианты в 3-4 раза быстрее).

Или придуматьб другую структуру, более подходящую для этой задачи.
...
Рейтинг: 0 / 0
Обновление словаря
    #40082133
swame2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kazantsev Alexey,

rtti это сразу намного медленее (на порядок). Какая тут оптимизация.
...
Рейтинг: 0 / 0
Обновление словаря
    #40082136
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
swame2
rtti это сразу намного медленее (на порядок). Какая тут оптимизация.

А если подумать?
...
Рейтинг: 0 / 0
Обновление словаря
    #40082140
swame2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kazantsev Alexey,

Добраться до FItems и GetBucketIndex, запомнить адреса и юзать напрямую ? можно, но выглядит как-то громоздко,
еще, и зависит от реализации RTL. Думаю что проще свою структуру сделать, но для этого данных в вопросе недостаточно.
...
Рейтинг: 0 / 0
25 сообщений из 36, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Обновление словаря
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]