powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TDictionary или TList<>.BinarySearch с позиции поиска
25 сообщений из 479, страница 4 из 20
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369251
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeySOFT FOR YOUПопробуй вот так :)
Стало чуть лучше, но всё равно отстой:
рандомные ключи 1млн: 7091 уникальный хеш
последовательные 1млн: 348 уникальных хешей
английский словарь 30322: 1580 уникальных хешей

А замер скорости времени поиска?
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369254
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SOFT FOR YOUKazantsev Alexeyпропущено...

Стало чуть лучше, но всё равно отстой:
пропущено...


А замер скорости времени поиска?
зачем нужен замер скорости, если сам хеш - говно ?
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369256
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUХаре лениться. Заколебали
Выложи dpr.
Мне лень переводить подсчёт коллизий со своей структуры на словарь. Поэтому нет.

SOFT FOR YOUЕщё я коллизии не считал
Дело хозяйское.
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369258
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUА замер скорости времени поиска?
Какой ещё замер скорости??? У тебя там сплошные коллизии.
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369260
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecatorSOFT FOR YOUпропущено...


А замер скорости времени поиска?
зачем нужен замер скорости, если сам хеш - говно ?

У меня в оригинале rol и bswap. Что в упрощенном паскале коллизий много - я удивлён
Нужен тестовый проект со скоростью поиска и с подсчётом коллизий. Можно будет посмотреть, что не так, докрутить функцию
И сравнить варианты между собой
Может Алексей что-то не так написал
А то без проекта можно с тем же успехом брать цифры с потолка и сюда постить
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369261
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SOFT FOR YOUА то без проекта можно с тем же успехом брать цифры с потолка и сюда постить

тебе код привёл, вставь в пустой проект эти 8 строчек
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369262
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUМожет Алексей что-то не так написал
А то без проекта можно с тем же успехом брать цифры с потолка и сюда постить
Я тебе все вводные дал - проверяй.
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369271
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ладно, вот вариант с 1 умножением:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
function StringHash(const Value: string): Integer;
var
  i: Integer;
  S: PChar;
begin
  S := Pointer(Value);
  Result := 0;
  if (S <> nil) then
  begin
    Result := PInteger(NativeInt(Value) - 4)^;

    for i := 1 to Result do
    begin
      Result := Result * i + Ord(S^);
      Inc(S);
    end;
  end;
end;



Уникальных: 999772, коллизий: 228
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369273
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Справедливости ради стоит сказать, что коллизии нужно считать не по хешу, а по младшим битам хеша в соответствии с размером таблицы
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369274
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUЛадно, вот вариант с 1 умножением:
...
Уникальных: 999772, коллизий: 228
Ну это на рандомных ключах, а на последовательных и на словаре всё равно дофига коллизий.
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369275
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUколлизии нужно считать не по хешу, а по младшим битам хеша в соответствии с размером таблицы
Сам-то понял, что сказал? Если у тебя хеши одинаковые, то и вход в таблицу ты получишь один и тот же.
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369276
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeySOFT FOR YOUЛадно, вот вариант с 1 умножением:
...
Уникальных: 999772, коллизий: 228
Ну это на рандомных ключах, а на последовательных и на словаре всё равно дофига коллизий.

Так я тебе поэтому и говорю
Код в студию
И замер времени поиска
Коллизий может быть сколько угодно, в конечном счёте важна скорость поиска
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369277
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeySOFT FOR YOUколлизии нужно считать не по хешу, а по младшим битам хеша в соответствии с размером таблицы
Сам-то понял, что сказал? Если у тебя хеши одинаковые, то и вход в таблицу ты получишь один и тот же.

Я к тому, что приведённый твой волшебный хеш на самом деле даёт значительно больше коллизий, чем ты думаешь
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369280
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUКоллизий может быть сколько угодно, в конечном счёте важна скорость поиска
SOFT FOR YOUЯ к тому, что приведённый твой волшебный хеш на самом деле даёт значительно больше коллизий, чем ты думаешь
Коллизия хеша однозначно приведёт к замедлению поиска. Это аксиома. Аксиомы доказательств не требуют. И кстати, тут никто не говорил, что у хорошей хеш-функции не будет коллизий при получении входа в таблицу (по крайней мере до тех пор, пока размерность хеша не совпадёт с размерностью таблицы), но у плохой их будет ещё больше.

Я сейчас попробовал заменить в своей таблице хеш Седжвика на твою функцию. До этого момента она в поиске была быстрее TDictionary на 159%, на последовательных ключах. C твоей функцией (последним её вариантом) я вообще не смог дождаться заполнения таблицы. Закономерный результат.
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369283
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeySOFT FOR YOUКоллизий может быть сколько угодно, в конечном счёте важна скорость поиска
SOFT FOR YOUЯ к тому, что приведённый твой волшебный хеш на самом деле даёт значительно больше коллизий, чем ты думаешь
Коллизия хеша однозначно приведёт к замедлению поиска. Это аксиома. Аксиомы доказательств не требуют. И кстати, тут никто не говорил, что у хорошей хеш-функции не будет коллизий при получении входа в таблицу (по крайней мере до тех пор, пока размерность хеша не совпадёт с размерностью таблицы), но у плохой их будет ещё больше.

Я сейчас попробовал заменить в своей таблице хеш Седжвика на твою функцию. До этого момента она в поиске была быстрее TDictionary на 159%, на последовательных ключах. C твоей функцией (последним её вариантом) я вообще не смог дождаться заполнения таблицы. Закономерный результат.

Если на одну позицию хеш-таблицы есть 1000 элементов - тогда да
А если на одну позицию ~2 элемента - тогда скорость поиска упирается в скорость функции. А для строк - это цикл по символам
У тебя синдром defecator-а? Сложно выложить тестовый проект?
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369285
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот проект по коллизиям
Хеш корректируется под размер таблицы (1048576)

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
program Hash;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Winapi.Windows,
  System.Generics.Collections,
  System.SysUtils,
  System.Classes;

const
  KEYS_COUNT = 1000000;

var
  i: NativeInt;
  HashValue: Integer;
  Keys: TArray<string>;
  Dictionary: TDictionary<Integer, Integer>;

function StringHash(const Value: string): Integer;
var
  i, X, Count: Integer;
  S: PByte;
begin
  S := Pointer(Value);
  Result := 0;
  if (S <> nil) then
  begin
    Count := PInteger(NativeInt(Value) - 4)^;

    Result := Count;
    for i := 1 to (Count shr (SizeOf(Char) xor 3)) do
    begin
      X := Result xor PInteger(S)^;
      Result := Result * i;
      Inc(Result, X shr 19);
      Inc(S, SizeOf(Integer));
      Inc(Result, X);
    end;

    for i := 1 to (Count and ((SizeOf(Char) xor 2) or 1)) do
    begin
      Result := Result * i;
      Inc(Result, Ord(PChar(S)^));
      Inc(S, SizeOf(Char));
    end;
  end;
end;

function GetHash(const Key: string): Integer;
var
  a: Integer;
  i: Integer;
begin
  Result := 0;
  a := 63689;
  for i := 1 to Length(Key) - 1 do
  begin
    Result := Result * a + PWordArray(Key)[i];
    a := a * 378551;
  end;
end;

begin
  try
    // заполнение
    SetLength(Keys, KEYS_COUNT);
    for i := Low(Keys) to High(Keys) do
      Keys[i] := TGuid.NewGuid.ToString;

    // уникальные
    Dictionary := TDictionary<Integer, Integer>.Create;
    try
      for i := Low(Keys) to High(Keys) do
      begin
        HashValue := StringHash{GetHash}(Keys[i]) and (1024 * 1024 - 1);
        Dictionary.AddOrSetValue(HashValue, 0);
      end;

      Writeln('Уникальных: ', Dictionary.Count, ', коллизий: ', KEYS_COUNT - Dictionary.Count);
    finally
      Dictionary.Free
    end;

    // нажать Enter
    Write('Press Enter');
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.



Код: plaintext
1.
2.
3.
StringHash:
Уникальных: 641331, коллизий: 358669
GetHash:
Уникальных: 644653, коллизий: 355347

Отдельно публикую быстрый StringHash
Работает по 4 байтам за итерацию, одно умножение, понимает как Unicode-версию Delphi, так и Ansi
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
function StringHash(const Value: string): Integer;
var
  i, X, Count: Integer;
  S: PByte;
begin
  S := Pointer(Value);
  Result := 0;
  if (S <> nil) then
  begin
    Count := PInteger(NativeInt(Value) - 4)^;

    Result := Count;
    for i := 1 to (Count shr (SizeOf(Char) xor 3)) do
    begin
      X := Result xor PInteger(S)^;
      Result := Result * i;
      Inc(Result, X shr 19);
      Inc(S, SizeOf(Integer));
      Inc(Result, X);
    end;

    for i := 1 to (Count and ((SizeOf(Char) xor 2) or 1)) do
    begin
      Result := Result * i;
      Inc(Result, Ord(PChar(S)^));
      Inc(S, SizeOf(Char));
    end;
  end;
end;
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369306
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUЕсли на одну позицию хеш-таблицы есть 1000 элементов - тогда да
А если на одну позицию ~2 элемента - тогда скорость поиска упирается в скорость функции. А для строк - это цикл по символам
В скорость функции всё упрётся только тогда, когда каждому выданному хешу будет соответствовать незанятая точка входа. В противном случае, чем больше коллизий даёт функция, тем медленнее работает таблица.

SOFT FOR YOUСложно выложить тестовый проект?
Сложно.

SOFT FOR YOUВот проект по коллизиям
Хеш корректируется под размер таблицы (1048576)

Подгоняем условия под результат? И снова удобные рандомные ключи На последовательных сделай, и посмотри. И кстати, не у всех таблиц внутренний размер кратен степени двойки.

Кстати, вот тебе для облегчения задачи готовый компарер для TDictionary:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
type
 TStringComparer = Class(TEqualityComparer<String>)
   function Equals(const Left, Right: String): Boolean; Override;
   function GetHashCode(const Value: String): Integer;Override;
 End;

{ TStringComparer }

function TStringComparer.Equals(const Left, Right: String): Boolean;
begin
 result := Left = Right;
end;

function TStringComparer.GetHashCode(const Value: String): Integer;
begin
 result := StringHash(value);
end;


Тестируем с последовательными ключами. С Седжвиком TDictionary ускоряется вдвое. С твоей функцией... сам проверь, если дождаться заполнения сумеешь. Моя таблица с твоим хешем медленне в 78(!) раз чем с Седжвиком. Ну и в качестве пищи для размышлений: TDictionary имеет размер внутренней таблицы кратный степени двойки, моя таблица нет. Удачи.
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369324
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeySOFT FOR YOUЕсли на одну позицию хеш-таблицы есть 1000 элементов - тогда да
А если на одну позицию ~2 элемента - тогда скорость поиска упирается в скорость функции. А для строк - это цикл по символам
В скорость функции всё упрётся только тогда, когда каждому выданному хешу будет соответствовать незанятая точка входа. В противном случае, чем больше коллизий даёт функция, тем медленнее работает таблица.

Чем по твоему грозит коллизия в "ячейке"?
Только тем, что будет вызвано на N сравнений больше, когда будет проход по записям с одинаковым хешем

Kazantsev AlexeySOFT FOR YOUСложно выложить тестовый проект?
Сложно.

Бред какой-то

Kazantsev AlexeySOFT FOR YOUВот проект по коллизиям
Хеш корректируется под размер таблицы (1048576)

Подгоняем условия под результат? И снова удобные рандомные ключи На последовательных сделай, и посмотри. И кстати, не у всех таблиц внутренний размер кратен степени двойки.

Причём здесь подгоняем? 1048576 - это следующее кратное 2 число после миллиона
Покажи хоть один промышленный хеш-массив с размером не равным степени двойки. И давай замерим его производительность
И что удобного в рандомных ключах? Там одинаковая длина и диапазон символов - 17
Где ты видел миллион строк "Index" + i ?
Даже миллион гвидов - задача, притянутая за уши. Ты же предлагаешь всерьёз воспринимать то, что реалиям не имеет никакого отношения. Но я согласен, в этих случаях лучше Седжвик

Kazantsev AlexeyТестируем с последовательными ключами. С Седжвиком TDictionary ускоряется вдвое. С твоей функцией... сам проверь, если дождаться заполнения сумеешь. Моя таблица с твоим хешем медленне в 78(!) раз чем с Седжвиком. Ну и в качестве пищи для размышлений: TDictionary имеет размер внутренней таблицы кратный степени двойки, моя таблица нет. Удачи.

Нет проекта - нет дискуссии
"Index" + i не имеют ничего общего с реальностью
Имеет значение не скорость добавления, а скорость поиска
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369329
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С Седжвиком TDictionary ускоряется вдвое.

Сейчас проверил на своем примере, с при подстановке компаратора с Седжвиком, поиск стал медленнее в 1.5 раза
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369332
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov,

А что было до Седжвика?
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369336
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatasviridenkov,

А что было до Седжвика?

Дефолтный компарер
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369341
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov,

А который у тебя дефорлтный?
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369343
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatasviridenkov,

А который у тебя дефорлтный?

Почему у меня, у TDictionary. Не знаю, что именно там.
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369344
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUЧем по твоему грозит коллизия в "ячейке"?
Только тем, что будет вызвано на N сравнений больше, когда будет проход по записям с одинаковым хешем
Ох и трудный же ты... Отсутствие коллизии хеша не гарантирует отсутствия коллизии на точке входа, зато коллизия хеша её присутствие гарантирует.

SOFT FOR YOUБред какой-то
Бред, это твой хеш.

SOFT FOR YOUПокажи хоть один промышленный хеш-массив с размером не равным степени двойки. И давай замерим его производительность
Я тебе ничего доказывать не собираюсь. У меня таблица именно такая, и насколько она опережает TDictionary я уже писал.

SOFT FOR YOUИ что удобного в рандомных ключах? Там одинаковая длина и диапазон символов - 17
А подумать? Идентификаторы сессий/объектов/дачегоугодновообще на сервере.

SOFT FOR YOUГде ты видел миллион строк "Index" + i ?
Это лишь синтетический пример. Последовательные ключи или ключи с постоянной частью это реальная проблема для хеш-функций. Ты бы знал об этом, если бы читал что-нибудь по теме. Поэтому универсальные хеши всегда тестируют на разных наборах данных, а не только на удобных.

SOFT FOR YOUНет проекта - нет дискуссии
Да бога ради. Если для тебя сложно вставить свой хеш в готовый компарер и проинициализировать им словарь, тут действительно не о чем больше говорить.

SOFT FOR YOUИмеет значение не скорость добавления, а скорость поиска
Мы бы и померили скорость поиска, если бы смогли заполнить таблицу с твоим хешем. Проблема в том, что я так долго ждать не могу
...
Рейтинг: 0 / 0
TDictionary или TList<>.BinarySearch с позиции поиска
    #39369345
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatБыстрый хэшик для строки.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
{$OverFlowChecks OFF}
function GetHash(const Key: String): integer;
var
  a : Integer;
  i : Integer;
begin
  Result:=0;
  a:=63689;
  for i:=1 To Length(Key)-1 do begin
    Result:=Result*a+PWordArray(Key)[i];
    a:=a*378551;
  end;
end;



А ведь кто-то может утащить в копилку алгоритм с ошибой )
...
Рейтинг: 0 / 0
25 сообщений из 479, страница 4 из 20
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TDictionary или TList<>.BinarySearch с позиции поиска
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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