Меню

О производительности на хеш-таблицах. Тест ни о чем

|

Отрадно, что тема произвотиельности на хеш-таблицах заинтересовала абапствующую публику. Устроим еще разок тест ни очем и продолжим злоберманью брехню.

«Никогда не поверю!»,
сказала женщина, увидев жирафа».

(поговорка)

Отрадно, что тема произвотиельности на хеш-таблицах заинтересовала абапствующую публику. Устроим еще разок тест ни очем и продолжим злоберманью брехню.

Однократное измерение малопредставительно, а потому протестируем обращение к хешированной внутренней таблице по тысяче раз для различных размеров внутеренней таблицы. Будем записывать результаты каждого измерения, дабы, отранжировав их, получить квантили. Известно, что первое обращение к внутренней таблице происходит дольше, чем остальные, а потому два первых обращения (к последней и первой записям) измерять не будем, и тем, надеюсь, отсеем (незаслуженно презираемые некоторыми абаперами) накладные расходы на всю таблицу, на что бы они там не шли, оставив расходы лишь на каждое отдельное обращение. Для каждого размера будем создавать внутреннюю таблицу заново, предварительно уничтожив предыдущее содержимое и освободив память (команда FREE). Размеры таблиц по-прежнему будем брать как последовательные целые степени двойки. Результаты для каждого размера отсоортируем, определим медиану и крайние квантили: кватрили, децили, сентили. (Поскольку измерений тысяча, максимальное и минимальное значения окажутся и крайними миллилями, но это, конечно непредставительно в силу их единственности). Как все конечно же помнят, между крайними кватрилями попадает половина значений, между крайними децилями 80%, между крайними сентилями 98%. Будем делать все это 1000 раз. Мне представляется важным, чтобы для каждого размера проводилось не по 1000 измерений к одной и той же таблице, но чтобы таблица перестраивалась перед каждым измерением (мы еще помним, что пару первых обращений делаем без измерения времени). Для любителей нормального распределения подсчитаем первый и второй моменты, среднеарифметическое и дисперсию, ну и среднеквадратическое отклонение от среднего. Текст программы приведен ниже.

Можете назвать Злоберманна трусливым койотом, но первые два обращения я не измеряю, а таблицу пересоздаю перед каждой последовательностью из этих трех обращений, то есть 1000 * 2^N раз. Поэтому программа работает несколько неспешно. Для 2^21 ~ 2 миллинов записей программа работала 3 тысячи секунд, для 2^25 ~ 33.5 миллионов – 72 тысячи секунд, то есть несколько менее суток.

Листинги приведены ниже. Видно, что и медиана, и среднеарифметическое значение времени чтения записи из хеш-таблицы таки зависят от размера. Видно, что отклонения в сторону больших времен имеют гораздо больший размах, чем отклонения в меньшую сторону, что, впрочем, не удивитильно, ибо при таком размахе противоположный результат означал бы, что ответ приходит раньше запроса. Возьму на себя смелость обратить внимание на те случаи, когда максимальное значение отличается от медианного в сотни(!) раз. Бытовой аналог этого таков: взять задание на день и вернуться с результатом через год. У заказчика или начальства могут возникнуть вопросы, и не только чисто академический «где черти носили» (что ты там делала, кроме вычисления хэш-функции), но и более практически значимый «на кого работаешь за мою зарплату» (время-то засчитывается на мою операцию READ TABLE).

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

Текст программ приведен ниже. Можно скопировать в свою систему и исполнить. А можно и модифицировать, например, проверить, какое влияние окажет запрет переноса данных (TRANSPORTING NO FIELDS). Заранее предостерегу желающих вычислять моменты высоких порядков и проводить очень большое число измерений: ABAP не работает с целыми числами, большими, чем 2 ^ 31 - 1, но можно использовать другие числовые типы.

И хорошо бы огласить результаты, если это представляется значимым.

Текст проги.

* 006.Perfomance on Hashed Table (1000 tests for each table size)
REPORT  ZQK006.
selection-screen comment /1(80) t_worn.
selection-screen begin of line.
selection-screen comment 1(24)  t_power.
parameters       p_power type i default 8.
selection-screen end of line.
data
: gp_rpt  type i value 1000           " test number
, begin     of gs                     " hashed table line
,   nnn   type n length 12
, end       of gs
, gt      like hashed table of gs with unique key nnn
, begin     of gs_stat                " statistics line
,   no    type int2
,   cnt   type int4
,   rls   type standard table of i    " realisation table
, end       of gs_stat
, gt_stat like standard table of gs_stat with key no
, gp_cnt  type int4                   " hashed table size
, gp_trg  like gs-nnn                 " line to be found
, a type i, b type i, t type i
, list_header type string
.
start-of-selection.
do gp_rpt times.                 " 1000 tests
  do p_power times.              " Each test
    gp_cnt = 2 ** sy-index.
    gp_trg = gp_cnt - 1.
    free gt.
    do gp_cnt times.
      add 1 to gs-nnn.
      insert gs into table gt.
    enddo.
    read table gt into gs with table key nnn = gp_trg.
    read table gt into gs with table key nnn = 1.
    get run time field a.
    read table gt into gs with table key nnn = gp_trg.
    get run time field b.
    t = b - a.                   " Result
    perform result_collection.
  enddo.                         " End of test
enddo.                           " End of 1000 tests
perform result_processing.
uline.

write                            " Legend
  : / 'Count    - Hashed table size = line count'
  , / 'Avg      - Average'
  , / 'Disp     - Dispersion'
  , / 'rMS      - Root mean square '

Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland

У вас уже есть учетная запись?

Войти

Обсуждения Количество комментариев14

Комментарий от  

Валерий Заузолков

  |  12 февраля 2015, 16:09

Не очень понял след.момент: "Мне представляется важным, чтобы для каждого размера проводилось не по 1000 измерений к одной и той же таблице, но чтобы таблица перестраивалась перед каждым измерением".
Но, насколько мне известно, назначение хэш-таблиц - это чтение по неизменяемым/малоизменяемым таблицам достаточного объема, т.е. когда наполнение таблицы происходит один раз и затем содержимое либо не меняется, либо мало меняется.
Поэтому мне видится, что для целей практического использования тест с 1000 чтениями по одному и тому же содержимому был бы ценней, чем 1 чтения по 1000 содержимым. Или ошибаюсь?

Комментарий от  

Денис Озорнов

  |  12 февраля 2015, 18:07

1) я солидарен с Влерием. Смысл очистки таблицы и повторного ее заполнения при таком тесте для меня не ясен. Это же не вытаскивание данных из СУБД.
 
2) в части раскидывания данных по квартилям, как мне кажется, это опять "ни о чем". По моему скромному мнению, тут бы скорее подошла гистограмма "сколько в штуках чтений пришлось на тот или иной участок стат.распределения". Такие данные были бы гораздо показательнее. Но, в принципе, и так видно, что большей частью все значения времени чтения сосредоточенны в левой части распределения.
 
3) повторюсь, как и в предыдущем обсуждении: есть аномальные значения, явно выбивающиеся из линейной корреляции(имея ввиду, что речь идет о вычислениях, а не о чтении СУБД, предположу, что это вызвано нагрузкой на железо апп.сервера, не связанной с работой программы), а так же - речь идет о микросекундех, т.е. отклонения по абсолютному значению времени не значительны, что и видно из вашего теста. (опять же, вспоминается хелп из версии 4.0, в котором обычно для каждой операции указывался разброс возможного времени выполнения в микросекундах)

Комментарий от  

Роман Семенов

  |  12 февраля 2015, 19:37

Согласен, действительно тест ни о чем.
Если бы вы действительно занимались оптимизацией, то вместо
read table gs_stat-rls into infq index 250.
использовали бы
read table gs_stat-rls assigning <fs> index 250.
 
В этом случае ваши замеры действительно показывали бы время обращения к таблице приближенное к реальности. А так, большая часть всех этих тысяч секунд потрачена на бесполезное копирование данных из таблицы в строку.
 
PS: ошибку исправьте в слове "полпадают".

Комментарий от  

Денис Озорнов

  |  17 февраля 2015, 21:29

В комментарии к статье призывается дух наполеона(зачеркнуто) того, кто любит себя называть Злоберманном. Или уважаемый (опять же это его самоназвание) "старый абапник" считает ниже своего достоинства вступать в полемику со спецами, с которыми он спешит поделится крупицами своего опыта? Нам следует ждать статью с опровержением комментариев опять через 2 месяца? Или все-таки можно надеяться постигнуть свои ошибки чуть ранее?

Комментарий от  

Оберманн З. Л.

  |  02 марта 2015, 13:25

Не очень понял след.момент: "Мне представляется важным, чтобы для каждого размера проводилось не по 1000 измерений к одной и той же таблице, но чтобы таблица перестраивалась перед каждым измерением".
Но, насколько мне известно, назначение хэш-таблиц - это чтение по неизменяемым/малоизменяемым таблицам достаточного объема, т.е. когда наполнение таблицы происходит один раз и затем содержимое либо не меняется, либо мало меняется.
Поэтому мне видится, что для целей практического использования тест с 1000 чтениями по одному и тому же содержимому был бы ценней, чем 1 чтения по 1000 содержимым. Или ошибаюсь?

1."Не очень понял след.момент:"
Я сторонник осторожного правила: не верить первому измерению.
 
1.1.Применительно к измерениям на базе данных это связано с тем, что базы при первом обращении могут еще не иметь запрошенных данных в буферах и по первому разу читать с дисков, а при повторах читать уже со своих буферов.
 
1.2.Применительно к измерениям на внутренних таблицах это означает, что точно (именно точно) не известно, как именно организован доступ. Если хотите, это выражение моего недоверия к документации.
 
1.3.Разумеется, это правило осторожности годится лишь для случаев, когда предполагаются многократные (2 это много?, а 3?) обращении в пределах короткого времени (секунды?, минуты?, года?).
 
2."Поэтому мне видится, что для целей практического использования тест с 1000 чтениями по одному и тому же содержимому был бы ценней, чем 1 чтения по 1000 содержимым. Или ошибаюсь?"
Меня интересовало максимальное разнообразие. Но я согласен, Ваша задача тоже интересна. Если Вы ей займетесь, пожалуйста, сообщите результаты.

Комментарий от  

Оберманн З. Л.

  |  02 марта 2015, 13:28

1) я солидарен с Влерием. Смысл очистки таблицы и повторного ее заполнения при таком тесте для меня не ясен. Это же не вытаскивание данных из СУБД.
 
2) в части раскидывания данных по квартилям, как мне кажется, это опять "ни о чем". По моему скромному мнению, тут бы скорее подошла гистограмма "сколько в штуках чтений пришлось на тот или иной участок стат.распределения". Такие данные были бы гораздо показательнее. Но, в принципе, и так видно, что большей частью все значения времени чтения сосредоточенны в левой части распределения.
 
3) повторюсь, как и в предыдущем обсуждении: есть аномальные значения, явно выбивающиеся из линейной корреляции(имея ввиду, что речь идет о вычислениях, а не о чтении СУБД, предположу, что это вызвано нагрузкой на железо апп.сервера, не связанной с работой программы), а так же - речь идет о микросекундех, т.е. отклонения по абсолютному значению времени не значительны, что и видно из вашего теста. (опять же, вспоминается хелп из версии 4.0, в котором обычно для каждой операции указывался разброс возможного времени выполнения в микросекундах)

1) "Можете называть Злоберманна трусливым койотом". См. Выше.
 
2) "в части раскидывания данных по квартилям, как мне кажется, это опять "ни о чем"."
Не могу согласиться. Квантили - общепринятый инструмент непараметрических статистик.
 
"По моему скромному мнению, тут бы скорее подошла гистограмма "сколько в штуках чтений пришлось на тот или иной участок стат.распределения". Такие данные были бы гораздо показательнее."
Намекаете, что могут быть дополнительные моды? Я их не жду, но этот вопрос я не исследовал. Займетесь?
 
Что до меня, то на данном этапе меня интересуют не особенности этого распределения. Меня интересует факт зависимости времени поиска по хэш-таблице от ее размера. Каковой факт и был продемонстрирован.
 
3) "повторюсь, как и в предыдущем обсуждении: есть аномальные значения, явно выбивающиеся из линейной корреляции"
Так она все же, есть линейная корреляция? Я не считал, но Вам верю на слово.
 
"предположу, что это вызвано нагрузкой на железо апп.сервера, не связанной с работой программы),"
Ну да. Производительность хэш таблицы таки зависит от размера. Именно таблицы. Производительность собственно алгоритма хеширования из-под АБАПа померить сложновато. Буду рад, если Вы найдете способ и сообщите.
 
"а так же - речь идет о микросекундех, т.е. отклонения по абсолютному значению времени не значительны, что и видно из вашего теста. (опять же, вспоминается хелп из версии 4.0, в котором обычно для каждой операции указывался разброс возможного времени выполнения в микросекундах)"
А как Вам 2 миллискенды? Точнее 1944 микросекунд.

Комментарий от  

Оберманн З. Л.

  |  02 марта 2015, 13:32

Согласен, действительно тест ни о чем.
Если бы вы действительно занимались оптимизацией, то вместо
read table gs_stat-rls into infq index 250.
использовали бы
read table gs_stat-rls assigning <fs> index 250.
 
В этом случае ваши замеры действительно показывали бы время обращения к таблице приближенное к реальности. А так, большая часть всех этих тысяч секунд потрачена на бесполезное копирование данных из таблицы в строку.
 
PS: ошибку исправьте в слове "полпадают".

"Если бы вы действительно занимались оптимизацией, то вместо"
И Вы ждете большой разницы при записи, состоящей из одного поля?
Позже надо будет заняться и этим.
 
"read table gs_stat-rls into infq index 250.
использовали бы
read table gs_stat-rls assigning <fs> index 250."
"index 250" нельзя: это хэш-таблица.
Но, раз это интересует абаствующую публику, то на досуге, быть может, сделаю
read table gt assigning <rec> with table key nnn = gp_trg.
 
"PS: ошибку исправьте в слове "полпадают"."
Спасибо. Приятно иметь внимательного читателя.

Комментарий от  

Оберманн З. Л.

  |  02 марта 2015, 13:32

В комментарии к статье призывается дух наполеона(зачеркнуто) того, кто любит себя называть Злоберманном. Или уважаемый (опять же это его самоназвание) "старый абапник" считает ниже своего достоинства вступать в полемику со спецами, с которыми он спешит поделится крупицами своего опыта? Нам следует ждать статью с опровержением комментариев опять через 2 месяца? Или все-таки можно надеяться постигнуть свои ошибки чуть ранее?

Поспешность хороша при ловле блох.
А вот подождать некоторое время придется. Злоберманн стремится к доказательности и старается не допускать голословных утверждений. Тем более, что читатели у меня замечательные, внимательные. Но вот работать тоже иногда приходится.
С одной стороны весьма отрадно, что тема Вас заинтересовала, но кроме того замечаю: переход на личности, фаллометрия, попытка троллинга.

Комментарий от  

Олег Точенюк

  |  02 марта 2015, 14:22

1) "Можете называть Злоберманна трусливым койотом". См. Выше.
 
2) "в части раскидывания данных по квартилям, как мне кажется, это опять "ни о чем"."
Не могу согласиться. Квантили - общепринятый инструмент непараметрических статистик.
 
"По моему скромному мнению, тут бы скорее подошла гистограмма "сколько в штуках чтений пришлось на тот или иной участок стат.распределения". Такие данные были бы гораздо показательнее."
Намекаете, что могут быть дополнительные моды? Я их не жду, но этот вопрос я не исследовал. Займетесь?
 
Что до меня, то на данном этапе меня интересуют не особенности этого распределения. Меня интересует факт зависимости времени поиска по хэш-таблице от ее размера. Каковой факт и был продемонстрирован.
 
3) "повторюсь, как и в предыдущем обсуждении: есть аномальные значения, явно выбивающиеся из линейной корреляции"
Так она все же, есть линейная корреляция? Я не считал, но Вам верю на слово.
 
"предположу, что это вызвано нагрузкой на железо апп.сервера, не связанной с работой программы),"
Ну да. Производительность хэш таблицы таки зависит от размера. Именно таблицы. Производительность собственно алгоритма хеширования из-под АБАПа померить сложновато. Буду рад, если Вы найдете способ и сообщите.
 
"а так же - речь идет о микросекундех, т.е. отклонения по абсолютному значению времени не значительны, что и видно из вашего теста. (опять же, вспоминается хелп из версии 4.0, в котором обычно для каждой операции указывался разброс возможного времени выполнения в микросекундах)"
А как Вам 2 миллискенды? Точнее 1944 микросекунд.

Вообще-то похоже измерения хэш-функции, плавно перетекли в измерения скорости доступа к данным находящимся в памяти системы. И тут уже вариантов просто вагон, начиная от типа операционной системы и заканчивая вариантами используемого менеджера памяти для никсовых систем (а их там в отличии от винды можно менять). По факту, кто сказал что таблица в памяти, да она может быть где угодно и чем больше таблица, тем вероятнее всего, что ее части находятся где-то вплоть до диска, что и вызывает аномальную задержку при чтении такого участка. Далее разбросы в 2-4 милисекунды, опять же ну попало в кеш процессора частичная команда, ну оно и сбросило весь кеш и загрузило его по новой от этой неполной команды и дальше что влезло (раньше влезало по 8 байт), вот вам и такты на перегруз кеша (кстати в хане это одно из достоинств, что микрокод выровнен по процессору и таких вот перегрузок не бывает), в общем смысла в этих милисекундах, если честно особо не вижу, кроме того что если таблица большая, то доступ, а фактически получение любой произвольной записи будет дольше, ну это как бы и так ясно должно было быть по причине описанной выше. Кстати доступ по индексу к любой большой таблице теоретически тоже должен возрастать при увеличении размера таблицы, хотя там вроде как считается все быстро.
 
Что касается самой хеш-функции, то вряд ли нам кто даст посмотреть на ее реализацию и соответственно оценить почему и как.
 
PS: По поводу синхронно/асинхронных обновлений я пока, к сожалению, системы где это можно смоделировать не имею, но про это помню :-), не смотрю на то что посты там потерли.

Комментарий от  

Денис Озорнов

  |  02 марта 2015, 16:39

1) "Можете называть Злоберманна трусливым койотом". См. Выше.
 
2) "в части раскидывания данных по квартилям, как мне кажется, это опять "ни о чем"."
Не могу согласиться. Квантили - общепринятый инструмент непараметрических статистик.
 
"По моему скромному мнению, тут бы скорее подошла гистограмма "сколько в штуках чтений пришлось на тот или иной участок стат.распределения". Такие данные были бы гораздо показательнее."
Намекаете, что могут быть дополнительные моды? Я их не жду, но этот вопрос я не исследовал. Займетесь?
 
Что до меня, то на данном этапе меня интересуют не особенности этого распределения. Меня интересует факт зависимости времени поиска по хэш-таблице от ее размера. Каковой факт и был продемонстрирован.
 
3) "повторюсь, как и в предыдущем обсуждении: есть аномальные значения, явно выбивающиеся из линейной корреляции"
Так она все же, есть линейная корреляция? Я не считал, но Вам верю на слово.
 
"предположу, что это вызвано нагрузкой на железо апп.сервера, не связанной с работой программы),"
Ну да. Производительность хэш таблицы таки зависит от размера. Именно таблицы. Производительность собственно алгоритма хеширования из-под АБАПа померить сложновато. Буду рад, если Вы найдете способ и сообщите.
 
"а так же - речь идет о микросекундех, т.е. отклонения по абсолютному значению времени не значительны, что и видно из вашего теста. (опять же, вспоминается хелп из версии 4.0, в котором обычно для каждой операции указывался разброс возможного времени выполнения в микросекундах)"
А как Вам 2 миллискенды? Точнее 1944 микросекунд.

1) нет, исследованиями такого рода не займусь, т.к. не вижу в них смысла, как в связи с вышеизложенными сомнениями в адекватности проведенных вами тестов, так и в связи с сомнениями в необходимости именно такого рода тестов
 
2) про аномальные значения я написал. То что корреляция линейна - в данному случае не определено формально. Этот вывод сделан исключительно "навскидку".

Комментарий от  

Денис Озорнов

  |  02 марта 2015, 16:41

Поспешность хороша при ловле блох.
А вот подождать некоторое время придется. Злоберманн стремится к доказательности и старается не допускать голословных утверждений. Тем более, что читатели у меня замечательные, внимательные. Но вот работать тоже иногда приходится.
С одной стороны весьма отрадно, что тема Вас заинтересовала, но кроме того замечаю: переход на личности, фаллометрия, попытка троллинга.

Что вы - что вы! Никакого троллинга! Всего лишь поддерживаю непринужденный тон авторской статьи. Алаверды, так сказать.

Комментарий от  

Оберманн З. Л.

  |  04 марта 2015, 21:55

Вообще-то похоже измерения хэш-функции, плавно перетекли в измерения скорости доступа к данным находящимся в памяти системы. И тут уже вариантов просто вагон, начиная от типа операционной системы и заканчивая вариантами используемого менеджера памяти для никсовых систем (а их там в отличии от винды можно менять). По факту, кто сказал что таблица в памяти, да она может быть где угодно и чем больше таблица, тем вероятнее всего, что ее части находятся где-то вплоть до диска, что и вызывает аномальную задержку при чтении такого участка. Далее разбросы в 2-4 милисекунды, опять же ну попало в кеш процессора частичная команда, ну оно и сбросило весь кеш и загрузило его по новой от этой неполной команды и дальше что влезло (раньше влезало по 8 байт), вот вам и такты на перегруз кеша (кстати в хане это одно из достоинств, что микрокод выровнен по процессору и таких вот перегрузок не бывает), в общем смысла в этих милисекундах, если честно особо не вижу, кроме того что если таблица большая, то доступ, а фактически получение любой произвольной записи будет дольше, ну это как бы и так ясно должно было быть по причине описанной выше. Кстати доступ по индексу к любой большой таблице теоретически тоже должен возрастать при увеличении размера таблицы, хотя там вроде как считается все быстро.
 
Что касается самой хеш-функции, то вряд ли нам кто даст посмотреть на ее реализацию и соответственно оценить почему и как.
 
PS: По поводу синхронно/асинхронных обновлений я пока, к сожалению, системы где это можно смоделировать не имею, но про это помню :-), не смотрю на то что посты там потерли.

«Вообще-то похоже измерения хэш-функции, плавно перетекли в измерения скорости доступа к данным находящимся в памяти системы.»

Это не к Злоберманну. Злоберманн писал только о времени доступа к хеш таблице. В обсуждении реализации алгоритма хеширования Злоберманн не участвует,

ибо из-под АБАПа это не доступно, а мои записки касаются именно АБАПа.

Комментарий от  

Олег Точенюк

  |  05 марта 2015, 16:39

«Вообще-то похоже измерения хэш-функции, плавно перетекли в измерения скорости доступа к данным находящимся в памяти системы.»

Это не к Злоберманну. Злоберманн писал только о времени доступа к хеш таблице. В обсуждении реализации алгоритма хеширования Злоберманн не участвует,

ибо из-под АБАПа это не доступно, а мои записки касаются именно АБАПа.

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

Комментарий от  

Оберманн З. Л.

  |  18 марта 2015, 00:40

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

>Ну так по факту все вылилось в определение доступа к памяти конкретной тестируемой системы,

Истина всегда конкретна (с)Г.В.Ф. Гегель

 

>а это не время доступа к хеш-таблице.

Напротив. Это именно оно. Абаперу АБАП дан только в конкретных системах

в конкретное время при конкретной загрузке этих систем прочими задачами

Все остальное из-под АБАПа недоступно

 

>Кстати можно запустить по такому же алгоритму, проверку времени доступа по индексу к стандартной таблице.

Непременно.

 

>Думаю время доступа будет тоже замедлятся с увеличением размеров этой таблицы, при произвольном чтении записей

Бинго! Именно так оно о и есть и никак не иначе! То, что индексный доступ к внутренним таблицам не зависит от размера, это тоже один из мифов.