Russian Qt Forum
Ноябрь 23, 2024, 15:42 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 3 [4] 5   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Ассоциативный контейнер для быстрого lookup'а  (Прочитано 31214 раз)
alexis031182
Гость
« Ответ #45 : Июль 19, 2012, 21:10 »

Вот, готово. Прошу пока не обращать внимания на "грязь" и отсутствие оптимизации, а где-то даже на откровенную глупость в тех участках кода, что не связаны напрямую с задачей. Мне важно было обыграть идею.

Ещё раз спасибо. Буду ожидать результата тестирования. Если возможно, то также укажите характеристики своей машины.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #46 : Июль 20, 2012, 10:54 »

Никаких проблем не возникло. Машина Intel Dual Xeon 2.6 (2х2 = 4 ядоа). Mac OSX (posix). Все компиляции в release,

493 (ms) - исходный на gcc 4.2
434  - icc 12.1

Доп тесты (icc)

161 - без qRand
517 - переставил qRand

Цитировать
//        qrand() % c.value(keys.at(i));
       c.value(keys.at(qrand() % keys.size()));

Разница между прогонами (для каждого варианта) незначительна (2-3 ms максимум) 
Записан
alexis031182
Гость
« Ответ #47 : Июль 20, 2012, 10:57 »

Что интересно: QHash выполняется в этом тесте за 70 мс. Для получения элемента использовал его функцию at(), которая предполагает отсутствие проверки на корректность ключа (это из Ассистента, да и практикой подтверждено).
Перегрелся вчера. У QHash нет функции at(). Используется value(). Значит, в 70 мс у QHash входит и проверка на корректность ключа.
Записан
alexis031182
Гость
« Ответ #48 : Июль 20, 2012, 11:03 »

...
Разница между прогонами (для каждого варианта) незначительна (2-3 ms максимум) 
Значит дело в машине. Только что попробовал Ваш вариант теста, разница 80-100 мс. Честно говоря, мне это непонятно.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #49 : Июль 20, 2012, 11:41 »

Значит дело в машине. Только что попробовал Ваш вариант теста, разница 80-100 мс. Честно говоря, мне это непонятно.
По-другому ложится в процессорный кеш.

Попробовал незатейливый QHash (переделать на него оказалось очень легко). Получил

31 - sum += c.value(keys.at(i));
300 - qrand() % c.value(keys.at(i));
382 - c.value(keys.at(qrand() % keys.size()));
266 - sum += qrand() % keys.size()
 
Записан
alexis031182
Гость
« Ответ #50 : Июль 20, 2012, 12:00 »

Попробовал незатейливый QHash (переделать на него оказалось очень легко). Получил

31 - sum += c.value(keys.at(i));
300 - qrand() % c.value(keys.at(i));
382 - c.value(keys.at(qrand() % keys.size()));
266 - sum += qrand() % keys.size()
QHash:
44 - "sum += c.value(keys.at(i));"
165 - "qrand() % c.value(keys.at(i));"
186 - "c.value(keys.at(qrand() % keys.size()));"
114 - "sum += qrand() % keys.size();"

Мой хэш:
0 - "sum += c.value(keys.at(i));"
101 - "qrand() % c.value(keys.at(i));"
105 - "c.value(keys.at(qrand() % keys.size()));"
91 - "sum += qrand() % keys.size();"
Записан
alexis031182
Гость
« Ответ #51 : Июль 22, 2012, 20:41 »

...
Мой хэш:
0 - "sum += c.value(keys.at(i));"
...
И стоило только эту сумму вывести в qDebug(), то результат тут же стал 93 мс Грустный
Записан
alexis031182
Гость
« Ответ #52 : Июль 22, 2012, 20:46 »

Сконструировал ещё один хэш, почитав соответствующую литературу. Но по прежнему не могу добиться превышения скорости над QHash. Самое интересное, что вроде и логика работы контейнера такая же, и алгоритм вычисления хэша строки беру быстрее (или такой же), а результат плачевный.

Стал разбираться с исходниками QHash. Ну практически один к одному, кроме того, что кол-во букетов у QHash формируется хитрым способом. Других различий, вроде, нет. А скорость разница аж в два раза Грустный
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #53 : Июль 23, 2012, 03:13 »

Непонятно на чем Вы хотите "сыграть". Др словами Вы берете общую задачу ассоциативного поиска и хотите ее ускорить. Так, на мой взгляд, шансов немного - общие вещи хорошо изучены и придумать что-то новое трудно. Ладно уж, общую критику велосипедизма опускаем  Улыбающийся

Но совсем др дело если бы учитывалась специфика задачи, пусть небольшая загогулина но все же вне общего случая. Вот тогда возможно далеко перегнать общие/стандартные решения. Пока я такой специфики не вижу.
Записан
alexis031182
Гость
« Ответ #54 : Июль 23, 2012, 10:37 »

Непонятно на чем Вы хотите "сыграть". Др словами Вы берете общую задачу ассоциативного поиска и хотите ее ускорить. Так, на мой взгляд, шансов немного - общие вещи хорошо изучены и придумать что-то новое трудно.
Я хочу разобраться, что является ускоряющим фактором у QHash. У меня нет лишних циклов (всё как у QHash), доступ к элементам в массивах по индексу (не QList, просто массив). Логика работы контейнера, вроде бы, одинаковая.

Если беру код вычисления хэша строки из QHash, то мой контейнер работает в 3 раза медленнее. Если беру более быстрый хэш, то в 2 раза медленнее. Значит дело не в хэше. Надо найти причину, из-за которой QHash выигрывает по скорости.

Ладно уж, общую критику велосипедизма опускаем  Улыбающийся
У меня изначально проект - велосипед

Но совсем др дело если бы учитывалась специфика задачи, пусть небольшая загогулина но все же вне общего случая. Вот тогда возможно далеко перегнать общие/стандартные решения. Пока я такой специфики не вижу.
Специфики особой нет. Известно лишь то, что ключей строго определённое кол-во, они не меняются в процессе работы приложения, и само собой изначально известны их значения. Этакий read-only контейнер.

Я пробовал соорудить Hash-контейнер для compile-time. У меня получилось. Я добился такой же скорости, как у QHash. Но там алгоритм вычисления хэша навороченный не вставить, т.к. принцип построения кода совсем другой (впрочем я уверен, что это возможно, просто недостаточно разбираюсь в этой теме). Из-за этого модернизацию compile-time хэша оставил пока до лучших времён.

Пока же задачу поставил разобраться с тонкостями QHash. Что делает его быстрее в сравнении с прямым указанием индексов в массиве?
Записан
alexis031182
Гость
« Ответ #55 : Июль 23, 2012, 12:05 »

Может ли скорость lookup'а в QHash быть выше из-за того, что ноды (Node) содержатся выравнено в памяти?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #56 : Июль 23, 2012, 15:51 »

В какой стандартный хеш у Вас? Напр если QHash <const char *, int>, то это может оказаться совсем не то (сравниваются адреса а не содержимое)
Записан
alexis031182
Гость
« Ответ #57 : Июль 23, 2012, 16:02 »

В какой стандартный хеш у Вас? Напр если QHash <const char *, int>, то это может оказаться совсем не то (сравниваются адреса а не содержимое)
Я просто изучаю исходники QHash и вижу, что там при одном условии может использоваться выравнивание в памяти для Node, где Node - это структура, являющаяся элементом контейнера и содержащая ключ, хэш ключа и значение элемента.

Однако функция выравнивания qMallocAligned() вызывается только если __alignof__(Node) возвратит число, большее 8 байт. Глянув на свой класс Node (он аналогичен), я получил размер в 4 байта. Другими словами, выравнивание в памяти - это не то, что я ищу. Вот ведь вешалка... Грустный
Записан
alexis031182
Гость
« Ответ #58 : Июль 23, 2012, 16:09 »

В аттач проект хэша присоединил. Алгоритм вычисления хэша ключа взят у QHash. Поиск по ключу выполняется в 3 раза медленнее, нежели чем у QHash.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #59 : Июль 23, 2012, 16:29 »

Вот я и спрашиваю с каким стандартным QHash Вы сравниваете. Если QHash <const char *, ...>, то он сравнивает адрес строки, что быстрее хотя и не то что нужно. Вычисление ключа я бы сделал так

Код
C++ (Qt)
uint32 hash( const char * str )
{
if (!str) return 0;
uint32 val = 0;
char * dst = (char *) &val;
size_t i = 0;
while (*str) {
 dst[i] ^= *str;
 ++str;
 i = (i + 1) % sizeof(val);
}
return val;
}
Записан
Страниц: 1 2 3 [4] 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.075 секунд. Запросов: 23.