Oberon space

General Category => Общий раздел => Тема начата: valexey_u от Сентябрь 09, 2016, 10:29:47 pm

Название: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 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 раза. См. табличку :-)
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 09, 2016, 11:46:45 pm
Кстати, результаты неплохо согласуются с http://lionet.info/pdf/2010-lev-walkin-erlang-experience.pdf
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 10, 2016, 01:56:36 am
Кстати, в камловой реализации unsafe была ошибка, сейчас исправил - решение стало тормозней в 2 раза. Зато через обычный array работает быстрее чем ожидалось.
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 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 версия.

И ещё, в версии на КП нет двух распечаток массива. Хоть массив и небольшой, но всё же скорость программы на КП завышенная получается...
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 10, 2016, 05:13:56 pm
Кстати, в версии на с++ используется доступ к элементам вектора с проверкой индексов, интересно, если использовать метод arr.at(i) без таких проверок -- намного шустрее будет?
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 10, 2016, 05:57:11 pm
at() - это как раз с проверкой индексов, а operator [] -- без.
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 10, 2016, 05:57:55 pm
Ocaml-косяк поправлю, спасибо.
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 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.
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 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 ббшный.
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 11, 2016, 09:37:23 pm
Нет желающих rust добавить? :-)
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 12, 2016, 07:13:49 pm
Я хотел добавить вариант с супербыстрым хаскельным вектором из пакета Data.Vector, но получил точно такой же результат, как с IOUArray. Странно...
Но, вообще, получается, что хаскельный вариант работает на уровне сишной программы с компилятором GCC, а учитывая, что GHC в качестве бекэнда использует как раз GCC, то резервов для ускорения хаскельной программы с текущим компилятором нет.
Когда-то обещали сделать версию GHC под LLVM, но пока не слышно об успехах этого порта...
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 12, 2016, 07:33:31 pm
Кстати, valexey_u, попробуй скомпилять хаскельный вариант с флагом -fllvm -- у тебя же установлен LLVM, так что вроде должен подхватиться компилятором GHC...
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 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.
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 12, 2016, 08:04:52 pm
Ну попробуй установить LLVM 3.7 )) Они наверное смогут параллельно работать...
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 12, 2016, 08:09:53 pm
Ну попробуй установить LLVM 3.7 )) Они наверное смогут параллельно работать...
Лениво :-) Попробуй лучше сам у себя все тесты прогнать. Я пока потихоньку готовлю вторую итерацию тестов. Чутка оптимизированных.
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 12, 2016, 08:22:53 pm
Я скачал LLVM 3.7, но какой-то он неполноценный -- нет программы opt в нём...
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 12, 2016, 08:29:37 pm
Я скачал LLVM 3.7, но какой-то он неполноценный -- нет программы opt в нём...
Ну, таким образом простому пользователю сия опция не доступна :-) Так что вычеркиваем.
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 12, 2016, 08:34:23 pm
Так я не понял -- эти LLVM-овцы специально сделали версию LLVM под винду без оптимизатора? а зачем он тогда такой нужен?
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 12, 2016, 09:45:06 pm
Этот LLVM под винду вообще какой-то неполноценный -- стандартных инклудников нет, нифига не компилирует с++-ный тест, например...
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 12, 2016, 10:03:29 pm
LLVM и не должен вроде как компилировать С++, С++ компилирует clang++ же.
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 12, 2016, 10:34:45 pm
ну там есть clang++.exe, но нет обычных хедер-файлов. Например, нет никаких iostream.*, vector.*...
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 14, 2016, 12:08:04 am
Смеха ради реализовал версию на js. Отрабатывает за 3.4 секунды с выводом на консоль и 2.8 секунды без вывода. То есть работает быстрее чем ББ, и при этом является более безопасным (контроль за границами массива включен).
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 14, 2016, 03:13:27 am
обновленная инфа - 2 секунды js.
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 14, 2016, 09:14:14 pm
А на своём трансляторе не пробовали?
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 14, 2016, 09:24:35 pm
Я подредактировал CP-шный вариант для простого Оберона:
MODULE Bubble;

IMPORT Out;

CONST n = 40000;

PROCEDURE PrintAll(arr: ARRAY OF INTEGER);
VAR i: INTEGER;
BEGIN
FOR i := 0 TO LEN(arr) - 1 DO
Out.Int(arr[i], 0);
Out.Ln
END
END PrintAll;

PROCEDURE DoIt*;
VAR
arr : ARRAY n OF INTEGER;
i, j, tmp : INTEGER;
BEGIN

FOR i := 0 TO n - 1 DO
arr[i] := n-i
END;

PrintAll(arr);
Out.String("---");
Out.Ln;

FOR i:=0 TO n-1 DO
FOR j:=0 TO n-2-i DO
tmp := arr[j];
IF arr[j] > arr[j+1] THEN
arr[j] := arr[j+1];
arr[j+1] := tmp
END
END
END;

PrintAll(arr)
END DoIt;

BEGIN
DoIt
END Bubble.
И прогнал через свой неполноценный транслятор. Оказалось, что на нём до сих пор не был реализован FOR. После добавления поддержки, транслятор выдал такое:
#include <stdlib.h>
#include <stddef.h>
#include <assert.h>
#include <math.h>
#include <stdbool.h>

#define n_cnst 40000

static void PrintAll_(int arr_[/*len0*/], int arr_len0) {
int i_;

for (i_ = 0; i_ <= arr_len0 - 1; ++i_) {
Out_Int(arr_[i_], 0);
Out_Ln();
}
}

extern void Bubble_DoIt(void) {
int arr_[n_cnst];
int i_;
int j_;
int tmp_;

for (i_ = 0; i_ <= n_cnst - 1; ++i_) {
arr_[i_] = n_cnst - i_;
}
PrintAll_(arr_, n_cnst);
Out_String("---", 4);
Out_Ln();
for (i_ = 0; i_ <= n_cnst - 1; ++i_) {
for (j_ = 0; j_ <= n_cnst - 2 - i_; ++j_) {
tmp_ = arr_[j_];
if (arr_[j_] > arr_[j_ + 1]) {
arr_[j_] = arr_[j_ + 1];
arr_[j_ + 1] = tmp_;
}
}
}
PrintAll_(arr_, n_cnst);
}

extern int main(int argc, char **argv) {
Bubble_DoIt();
return 0;
}
При сборке gcc -O3
программа работает 2.19 секунд
для сравнения, c++ вариант отработал за 2.1
и стабильно выполняется быстрей.
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 14, 2016, 09:34:07 pm
А на своём трансляторе не пробовали?
Пробовали. Те же 2 секунды примерно.

В общем, обновлю на гитхабе инфу и тесты, можно будет воспроизводить.
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 14, 2016, 09:36:01 pm
Я подредактировал CP-шный вариант для простого Оберона:
...
И прогнал через свой неполноценный транслятор. Оказалось, что на нём до сих пор не был реализован FOR. После добавления поддержки, транслятор выдал такое:
...
При сборке gcc -O3
программа работает 2.19 секунд
для сравнения, c++ вариант отработал за 2.1
и стабильно выполняется быстрей.

А где-то можно пощупать транслятор?
gcc на данном варианте тормоз, лучше щупать clang++.
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 14, 2016, 09:40:11 pm
Пока нигде, но скоро выложу на github.
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 14, 2016, 09:43:10 pm
gcc на данном варианте тормоз, лучше щупать clang++.
Действительно, clang даёт результат 1.35
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 15, 2016, 06:26:28 pm
gcc на данном варианте тормоз, лучше щупать clang++.
Действительно, clang даёт результат 1.35
Выходит, что твой кросскомпилер Оберон->C более эффективен, чем компилятор Блекбокса? Тебе надо срочно перевести Блекбокс на твой компилятор ))) Всё русское оберон-сообщество тебе огромное спасибо скажет. Правда, не заплатит ни копейки )))
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 15, 2016, 06:36:22 pm
gcc на данном варианте тормоз, лучше щупать clang++.
Действительно, clang даёт результат 1.35
Выходит, что твой кросскомпилер Оберон->C более эффективен, чем компилятор Блекбокса? Тебе надо срочно перевести Блекбокс на твой компилятор ))) Всё русское оберон-сообщество тебе огромное спасибо скажет. Правда, не заплатит ни копейки )))
Ну, тут же нет проверки индексов!
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 16, 2016, 01:43:17 pm
Выходит, что твой кросскомпилер Оберон->C более эффективен, чем компилятор Блекбокса? Тебе надо срочно перевести Блекбокс на твой компилятор ))) Всё русское оберон-сообщество тебе огромное спасибо скажет. Правда, не заплатит ни копейки )))
Ценю Ваш юмор.
Но если серьёзно, то, по-моему, лучше создать новую ОС-среду, полностью написанную сообществом и лишённую недостатков Блэкбокса.
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 16, 2016, 04:55:23 pm
Но если серьёзно, то, по-моему, лучше создать новую ОС-среду, полностью написанную сообществом и лишённую недостатков Блэкбокса.
Такой вариант уж точно не взлетит. Оберонщики и так уже разобщены кучей версий трансляторов, сред, ещё одна новая среда без библиотек и с несовместимым ни с кем транслятором -- этого никто не оценит...
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 16, 2016, 08:53:19 pm
Ну, тут же нет проверки индексов!
Как ни смешно, но не совсем правда. Поскольку транслируется  в Си, то проверка индексов может быть дана сишным компилятором.
Сейчас проверил с опциями -fsanitize=address -fsanitize=undefined.
gcc  2.5
clang 3.6

Выход за границы массива срабатывает.
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 16, 2016, 08:55:25 pm
Ну, тут же нет проверки индексов!
Как ни смешно, но не совсем правда. Поскольку транслируется  в Си, то проверка индексов может быть дана сишным компилятором.
Сейчас проверил с опциями -fsanitize=address -fsanitize=undefined.
gcc  2.5
clang 3.6

Выход за границы массива срабатывает.

Да, я знаю. Относительно недавняя фича в плане отлова UB в рантайме.
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 17, 2016, 05:37:43 pm
Попробовал в трёх браузерах выполнить оберон-жс вариант этого теста https://gist.github.com/valexey/e559764622f1b35ce9da799dbcc9e286
У файрфокса действительно какой-то аномально быстрый интерпретатор яваскрипта, скорость лучше чем у GCC и хаскеля:

Firefox 45.3.0 (Tor 6.0.4): 1.4 сек
Iron 52.0.2750.0 (на базе Chrome): 6.3 сек
Opera 12.18: 31 сек
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 17, 2016, 06:33:50 pm
А если убрать вывод в с++? У меня при перенаправлении вывода в /dev/null время сокращалось раза в 3
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 17, 2016, 07:36:42 pm
Проверил у себя на Blackbox 1.6. Собрать без проверок границ не получилось, но с проверкой получилось 3.35 секунд, что подозрительно, так как у меня все теcты, кроме этого, проходят медленней, чем у Алексея.

Процессор: Intel Core i3-4160
Вывод в консоль: отключён.

g++ -fsanitize=address -O3         : 1.6 сек
clang++ -fsanitize=address -O3 : 1.8 сек
Go                                                    : 1.8 сек
BlackBox                                         : 3.4 сек

Нет ли тут злого умысла  ;D?
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Сентябрь 17, 2016, 08:06:50 pm
А если убрать вывод в с++? У меня при перенаправлении вывода в /dev/null время сокращалось раза в 3
Проверил с GCC -- разница всего в 11% (делал вывод в файл, а не в /dev/null).
На хаскелле практически не было разницы между выводом в файл и без вывода -- разница в пределах погрешности измерения.

c++ с выводом в файл: 1.6 сек
c++ без вывода в файл: 1.4 сек
хаскель с выводом в файл: 1.7 сек
хаскель без вывода в файл: 1.7 сек
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 17, 2016, 08:11:33 pm
Проверил у себя на Blackbox 1.6. Собрать без проверок границ не получилось, но с проверкой получилось 3.35 секунд, что подозрительно, так как у меня все теcты, кроме этого, проходят медленней, чем у Алексея.

Процессор: Intel Core i3-4160
Вывод в консоль: отключён.

g++ -fsanitize=address -O3         : 1.6 сек
clang++ -fsanitize=address -O3 : 1.8 сек
Go                                                    : 1.8 сек
BlackBox                                         : 3.4 сек

Нет ли тут злого умысла  ;D?

Конечно есть! Я, как истинный злодей, запускал BB под Wine в линухе. Ну и система у меня 64битная. О чем и указал в ридмишке.

А какая конфигурация у тебя?
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 17, 2016, 08:15:56 pm
Да, до кучи у меня ББ версии 1.7.
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 17, 2016, 09:06:46 pm
Ubuntu 16.04 64 bit
wine 1.6.2
Blackbox 1.6

Но в GNU/Linux 64 разрядной версии Blackbox - http://oberon.molpit.com/packs/bbcb_1.7~a1.8_amd64.deb (http://oberon.molpit.com/packs/bbcb_1.7~a1.8_amd64.deb) у меня получился тот же результат.

Как выяснилось, вывод у меня тормозил из-за того, что я использую Terminator в качестве эмулятора терминала. В стандартном гномовском вывод не имеет весомой доли.
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 17, 2016, 09:12:29 pm
Ubuntu 16.04 64 bit
wine 1.6.2
Blackbox 1.6

Но в GNU/Linux 64 разрядной версии Blackbox - http://oberon.molpit.com/packs/bbcb_1.7~a1.8_amd64.deb (http://oberon.molpit.com/packs/bbcb_1.7~a1.8_amd64.deb) у меня получился тот же результат.

Как выяснилось, вывод у меня тормозил из-за того, что я использую Terminator в качестве эмулятора терминала. В стандартном гномовском вывод не имеет весомой доли.

Дык ББ вроде 64битной версии не бывает. Компилятор не умеет 64бита делать. То есть один фиг бинарь исполняется 32битный.

Все тесты (кроме ББшного) тестируются как time ./program > /dev/null

Вообще же вывод сделан для того, чтобы:

1) Проверить алгоритм на корректность (и это, кстати, окупилось - одна окамловая версия гнала пургу из за моей невнимательности и незнания языка).

2) Чтобы шибко умный компилятор не выкинул цикл с рассчетом.
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Сентябрь 17, 2016, 09:29:45 pm
Тогда всё сходится. Без вывода остальные программы работают быстрей, не только в ББ.

clang (o7 -> c) - 0.49 сек
clang++ (cpp)  - 0.53 сек
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 17, 2016, 09:44:03 pm
Тогда всё сходится. Без вывода остальные программы работают быстрей, не только в ББ.

clang (o7 -> c) - 0.49 сек
clang++ (cpp)  - 0.53 сек

Корректней это назвать "с выводом" с т.з. программы, просто вывод перенаправлен в /dev/null. Но программа то честно пишет в stdout и не в курсе, что можно было бы ничего не писать, ничего не считать, и никто этого не заметил бы :-)

Просто /dev/null это очень быстрое устройство вывода, в отличие от вывода на консоль например. Или вывода в обычный файл.
Название: Re: Простейший тест на производительность.
Отправлено: Ivan Denisov от Сентябрь 20, 2016, 06:32:55 pm
Ubuntu 16.04 64 bit
wine 1.6.2
Blackbox 1.6

Но в GNU/Linux 64 разрядной версии Blackbox - http://oberon.molpit.com/packs/bbcb_1.7~a1.8_amd64.deb (http://oberon.molpit.com/packs/bbcb_1.7~a1.8_amd64.deb) у меня получился тот же результат.

Как выяснилось, вывод у меня тормозил из-за того, что я использую Terminator в качестве эмулятора терминала. В стандартном гномовском вывод не имеет весомой доли.
Не стоит обманываться названием пакета. Это просто сборка для amd64. Приходится разделять из-за проблем с зависимостями.  А сам ББ внутри 32-битный. Проблема из-за того, что не существует пакета gnome-icon-theme-full:i386. Поэтому пакета для bbcb оказалось теперь два. Но зато человеческий диалог выбора файлов :)

Название: Re: Простейший тест на производительность.
Отправлено: Ivan Denisov от Сентябрь 20, 2016, 06:56:42 pm
У меня на bbcb для Ubuntu 14.04 на Core i5-3337U CPU @ 1.80GHz × 4

С проверкой 6.23
Без проверки 3.23

Алексей, еще бы на топовых компиляторах протестировать
https://software.intel.com/en-us/intel-compilers

А этот тест выдерживает критику QWERTYProgrammer ?
http://forum.oberoncore.ru/viewtopic.php?f=61&t=4482&p=82278&hilit=ifort#p82223
Название: Re: Простейший тест на производительность.
Отправлено: valexey_u от Сентябрь 20, 2016, 07:15:46 pm
У меня на bbcb для Ubuntu 14.04 на Core i5-3337U CPU @ 1.80GHz × 4

С проверкой 6.23
Без проверки 3.23

Алексей, еще бы на топовых компиляторах протестировать
https://software.intel.com/en-us/intel-compilers

А этот тест выдерживает критику QWERTYProgrammer ?
http://forum.oberoncore.ru/viewtopic.php?f=61&t=4482&p=82278&hilit=ifort#p82223

Ну, интелёвый компилер далеко не всегда сильно у актуального gcc or clang выигрывает, иногда даже проигрывает.

Да, и изначально тут тест производительности не столько компиляторов и языков как таковых, а связки человек + язык + компилятор. То есть вот да, в меру криворукий программист написал какой-то код на языке X и собрал это дело компилятором Y, какой результат производительности он получит и насколько нетривиальные шаги ему придется предпринять, чтобы ускорить этот код?

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

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

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

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

Ну и так далее.

Ну и тестировал я в первую очередь пригодность ocaml и haskell для подобных алгоритмов (с мутабельными данными, а точнее - массивами), камло оказалось более пригодным, хотя haskell в итоге показал результат (по скорости) не хуже.

PS. не забываем, что этот алгоритм - банальная сортировка пузырьком. простейший алгоритм. Если даже для подобного приходится как-то изворачиваться, тратить кучу времени и экспериментов для достижения производительности, переписывать код в другой манере и так далее, то связка язык + компилятор не очень хороша как минимум для быстрого прототипирования, так как по итогам такого прототипирования сама идея может быть забракована, ибо прототип покажет, что производительность получается СЛИШКОМ низкая. Либо придется тратить время на нетривиальное вылизывание кода в сторону производительности, но это противоречит самой идее быстрого прототипирования - это уже не быстро.
Название: Re: Простейший тест на производительность.
Отправлено: Kemet от Октябрь 02, 2016, 11:10:23 am
Я тут немного пошаманил на предмет замера в А2.

MODULE BubbleTest;

IMPORT Kernel, Heaps, Objects, Commands, Machine;

CONST n = 40000;

   PROCEDURE{ALIGNED(16), ALIGNSTACK(16)} DoIt*( context: Commands.Context );
   BEGIN
      DoSafe(context);
      DoUnchecked(context);
   END DoIt;

   PROCEDURE{ALIGNED(16), ALIGNSTACK(16)} DoSafe*( context: Commands.Context );
   VAR
      i, j, tmp: LONGINT;
      mhz, time0, time: HUGEINT;
      arr: ARRAY n OF LONGINT;
   BEGIN
      mhz := EstimateCpuClockrate( );
      time0 := Objects.CurrentProcessTime( );
      FOR i := 0 TO n - 1 DO
         arr[ i ] := n - i;
      END;

      FOR i := 0 TO n - 1 DO
         FOR j := 0 TO n - 2 - i DO
            IF arr[ j ] > arr[ j + 1 ] THEN
               tmp := arr[ j ];
               arr[ j ] := arr[ j + 1 ];
               arr[ j + 1 ] := tmp;
            END;
         END;
      END;
      time := Objects.CurrentProcessTime( );
      
      context.out.String("Safe: ");
      context.out.Int( ( time - time0 ) DIV ( 1000 * mhz), 1 ); context.out.String(" ms");
      context.out.Ln;
   END DoSafe;

   PROCEDURE{ALIGNED(16), ALIGNSTACK(16)} DoUnchecked*( context: Commands.Context );
   VAR
      i, j, tmp: LONGINT;
      mhz, time0, time: HUGEINT;
      arr{ALIGNED(16)}: ARRAY n OF LONGINT;
   BEGIN{UNCHECKED}
      mhz := EstimateCpuClockrate( );
      time0 := Objects.CurrentProcessTime( );
      FOR i := 0 TO n - 1 DO
         arr[ i ] := n - i;
      END;

      FOR i := 0 TO n - 1 DO
         FOR j := 0 TO n - 2 - i DO
            IF arr[ j ] > arr[ j + 1 ] THEN
               tmp := arr[ j ];
               arr[ j ] := arr[ j + 1 ];
               arr[ j + 1 ] := tmp;
            END;
         END;
      END;
      time := Objects.CurrentProcessTime( );

      context.out.String("Unchecked: ");
      context.out.Int( ( time - time0 ) DIV ( 1000 * mhz), 1 ); context.out.String(" ms");
      context.out.Ln;
   END DoUnchecked;

   
   PROCEDURE EstimateCpuClockrate(): HUGEINT;
   VAR
      timer : Kernel.Timer; milliTimer : Kernel.MilliTimer;
      startTime, endTime, timeDiff : HUGEINT;
      nbrOfGcRuns : LONGINT;
   BEGIN
      NEW(timer); nbrOfGcRuns := Heaps.Ngc;
      Kernel.SetTimer(milliTimer, 1000);
      startTime := Machine.GetTimer();
      WHILE ~Kernel.Expired(milliTimer) DO
         timer.Sleep(1);
         IF nbrOfGcRuns # Heaps.Ngc THEN RETURN 0; END;
      END;
      endTime := Machine.GetTimer();
      IF nbrOfGcRuns # Heaps.Ngc THEN RETURN 0; END;
      timeDiff := endTime - startTime;
      RETURN SHORT (timeDiff DIV (1000*1000));
   END EstimateCpuClockrate;

END BubbleTest.

BubbleTest.DoIt ~

BubbleTest.DoSafe~
BubbleTest.DoUnchecked~

SystemTools.Free BubbleTest ~
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Октябрь 02, 2016, 05:09:53 pm
      i, j, tmp: LONGINT;
      arr: ARRAY n OF LONGINT;
У тебя тут длинные целые (64 бита, видимо?), а у валексея и у меня просто целые (32 бита вроде). Это может влиять на скорость...
Название: Re: Простейший тест на производительность.
Отправлено: Romiras от Октябрь 02, 2016, 08:53:35 pm
      i, j, tmp: LONGINT;
      arr: ARRAY n OF LONGINT;
У тебя тут длинные целые (64 бита, видимо?), а у валексея и у меня просто целые (32 бита вроде). Это может влиять на скорость...
В Обероне LONGINT разве не 32 битные?
Название: Re: Простейший тест на производительность.
Отправлено: Kemet от Октябрь 04, 2016, 11:59:50 am
      i, j, tmp: LONGINT;
      arr: ARRAY n OF LONGINT;
У тебя тут длинные целые (64 бита, видимо?), а у валексея и у меня просто целые (32 бита вроде). Это может влиять на скорость...
В Активном Обероне LONGINT = SIGNED32, HUGEINT=SIGNED64
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Ноябрь 03, 2016, 10:32:07 am
Попробовал сделать на Rust'е, работает ну очень как-то медленно.
fn print_all(arr: &[i32]) {
    for i in 0..arr.len() {
        println!("{}", arr[i]);
    }   
}


fn main() {
    const N: usize = 40000;
    let mut arr: [i32; N] = [0; N];

    for i in 0..arr.len() { arr[i] = (N-i) as i32; }

    print_all(&arr);
    println!("-----");

    for i in 0..arr.len() {
        for j in 0..arr.len() - 1 - i {
            let tmp = arr[j];
            if  arr[j] > arr[j + 1] {
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
    print_all(&arr);
}
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Ноябрь 03, 2016, 10:39:06 am
Попробовал сделать на Rust'е, работает ну очень как-то медленно.
Это я её без опции -O компилил, с этой опцией стало весьма шустро работать.
Алексей, затести и добавь в таблицу результатов ))
Название: Re: Простейший тест на производительность.
Отправлено: kkkk от Ноябрь 03, 2016, 01:20:15 pm
Можно ещё ускорить с опцией -C ltoВозможно, из-за того, что 0..arr.len()является синтаксическим сахаром для
std::ops::Range {start: 0, end: arr.len()}
Название: Re: Простейший тест на производительность.
Отправлено: Geniepro от Ноябрь 04, 2016, 04:14:52 pm
Нет желающих rust добавить? :-)
Ну я добавил, и что, и где?  :o