Автор Тема: Простейший тест на производительность.  (Прочитано 2224 раз)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3009
    • Просмотр профиля
Простейший тест на производительность.
« : Сентябрь 09, 2016, 10:29:47 pm »
Собственно я тут с ocaml играюсь, соответственно хотел удостовериться что он более-менее применим на императивных алгоритмов (коих большинство на моих задачах - изображение обработать, обработать данные с датчика (десятки и сотни миллионов элементов в массиве и проч), что не будет внезапных просадок производительности раз эдак в 10 по сравнению с плюсами.

Посему соорудил простейший тест - обычная сортировка пузырьком массива из 40000 элементов (int), массив первоначально отсортирован в обратном порядке, следовательно максимальное число перестановок потребуется.

Ну а поскольку сложно удержаться и не потестить другие ЯП, в итоге было потестировано: ocaml, c++, go, haskell (спасибо geniepro за все варианты кода), component pascal / blackbox.

Итоги выложил на github: https://github.com/valexey/bubble_test

По итогам скажу, что ocaml меня не разочаровал - производительность всего на 20 процентов ниже плюсовой, и достигается очень просто в отличие от haskell'я, где нужно побегать и попрыгать, чтобы он не сливал позорно более чем в 10 раз плюсам.

Ну а Компонентный Паскаль с отключенными проверками на выход за пределы массива, отстает от С++ более чем в 4 раза. См. табличку :-)
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3009
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #1 : Сентябрь 09, 2016, 11:46:45 pm »
Кстати, результаты неплохо согласуются с http://lionet.info/pdf/2010-lev-walkin-erlang-experience.pdf
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3009
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #2 : Сентябрь 10, 2016, 01:56:36 am »
Кстати, в камловой реализации unsafe была ошибка, сейчас исправил - решение стало тормозней в 2 раза. Зато через обычный array работает быстрее чем ожидалось.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1949
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #3 : Сентябрь 10, 2016, 05:04:49 pm »
Что-то Go быстрее, чем я думал о_О чой-то он так???

Кстати, у тебя ведь в файле https://github.com/valexey/bubble_test/blob/master/ocaml/bubble_safe.ml используется в одном месте unsafe-операция:
let tmp = Array1.unsafe_get arr j in
то есть это тоже не совсем safe версия.

И ещё, в версии на КП нет двух распечаток массива. Хоть массив и небольшой, но всё же скорость программы на КП завышенная получается...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1949
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #4 : Сентябрь 10, 2016, 05:13:56 pm »
Кстати, в версии на с++ используется доступ к элементам вектора с проверкой индексов, интересно, если использовать метод arr.at(i) без таких проверок -- намного шустрее будет?
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3009
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #5 : Сентябрь 10, 2016, 05:57:11 pm »
at() - это как раз с проверкой индексов, а operator [] -- без.
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3009
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #6 : Сентябрь 10, 2016, 05:57:55 pm »
Ocaml-косяк поправлю, спасибо.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1949
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #7 : Сентябрь 10, 2016, 06:49:36 pm »
at() - это как раз с проверкой индексов, а operator [] -- без.
хм, и правда о_О http://www.cplusplus.com/reference/vector/vector/at/
Цитировать
std::vector::at
      reference at (size_type n);
const_reference at (size_type n) const;
Access element
 Returns a reference to the element at position n in the vector.

 The function automatically checks whether n is within the bounds of valid elements in the vector, throwing an out_of_range exception if it is not (i.e., if n is greater than, or equal to, its size). This is in contrast with member operator[], that does not check against bounds.
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3009
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #8 : Сентябрь 11, 2016, 06:19:32 pm »
Что-то Go быстрее, чем я думал о_О чой-то он так???
А они похоже научились в подобных случаях выпиливать проверки на выход за границы массива.

Кстати, у тебя ведь в файле https://github.com/valexey/bubble_test/blob/master/ocaml/bubble_safe.ml используется в одном месте unsafe-операция:
let tmp = Array1.unsafe_get arr j in
то есть это тоже не совсем safe версия.
Пофиксил. Еще раз тесты прогнал, результаты обновил.

И ещё, в версии на КП нет двух распечаток массива. Хоть массив и небольшой, но всё же скорость программы на КП завышенная получается...
Да, но я не представляю себе как на BB запущенном под Wine что-то эффективно вывести на stdout. То есть так как сейчас это значительно честнее чем если я буду сейчас колхозить на ББ любой вывод массивов в консоль или вообще в log ббшный.
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3009
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #9 : Сентябрь 11, 2016, 09:37:23 pm »
Нет желающих rust добавить? :-)
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1949
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #10 : Сентябрь 12, 2016, 07:13:49 pm »
Я хотел добавить вариант с супербыстрым хаскельным вектором из пакета Data.Vector, но получил точно такой же результат, как с IOUArray. Странно...
Но, вообще, получается, что хаскельный вариант работает на уровне сишной программы с компилятором GCC, а учитывая, что GHC в качестве бекэнда использует как раз GCC, то резервов для ускорения хаскельной программы с текущим компилятором нет.
Когда-то обещали сделать версию GHC под LLVM, но пока не слышно об успехах этого порта...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1949
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #11 : Сентябрь 12, 2016, 07:33:31 pm »
Кстати, valexey_u, попробуй скомпилять хаскельный вариант с флагом -fllvm -- у тебя же установлен LLVM, так что вроде должен подхватиться компилятором GHC...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3009
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #12 : Сентябрь 12, 2016, 07:52:37 pm »
Кстати, valexey_u, попробуй скомпилять хаскельный вариант с флагом -fllvm -- у тебя же установлен LLVM, так что вроде должен подхватиться компилятором GHC...
ghc от моего llvm тошнит и пучит:
$ ghc -fllvm -O3 bubble_unsafe_array.hs
[1 of 1] Compiling Main             ( bubble_unsafe_array.hs, bubble_unsafe_array.o )
You are using an unsupported version of LLVM!
Currently only 3.7 is supported.
We will try though...
opt: /tmp/ghc22577_0/ghc_2.ll:15:29: error: expected comma after alias's type
@__stginit_Main = alias i8* bitcast (%__stginit_Main_struct* @__stginit_Main$def to i8*)
                            ^
`opt' failed in phase `LLVM Optimiser'. (Exit code: 1)

У меня слишком свежий llvm.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1949
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #13 : Сентябрь 12, 2016, 08:04:52 pm »
Ну попробуй установить LLVM 3.7 )) Они наверное смогут параллельно работать...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3009
    • Просмотр профиля
Re: Простейший тест на производительность.
« Ответ #14 : Сентябрь 12, 2016, 08:09:53 pm »
Ну попробуй установить LLVM 3.7 )) Они наверное смогут параллельно работать...
Лениво :-) Попробуй лучше сам у себя все тесты прогнать. Я пока потихоньку готовлю вторую итерацию тестов. Чутка оптимизированных.
Y = λf.(λx.f (x x)) (λx.f (x x))