Тема: Erlang запитання - відповіді -- обговорення
тема для обговорення теми http://replace.org.ua/post/79625/ з прикладами по Erlang --
все обговорення - сюди
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → Інші мови програмування → Erlang → Erlang запитання - відповіді -- обговорення
Сторінки 1
Для відправлення відповіді ви повинні увійти або зареєструватися
тема для обговорення теми http://replace.org.ua/post/79625/ з прикладами по Erlang --
все обговорення - сюди
Ну якщо вже порівнювати ефективність алгоритмів для чисел Фібоначчі, то варто розглянути і інші, більш ефективні алгоритми, зокрема формулу, яка має виконуватися приблизно за час O(1).
Мені цікаво як в Erlang буде виглядати код для такої формули.
дякую за цікаве-слушне зауваження -
немає границь для вдосконалення)
як я зрозумів із того що уже потицяв на практиці - у ерлангу код для однієї і тієї ж формули може виглядати по-різному (тобто бути написаний різними шляхами), відповідно і працювати по-різному
вранці/в обід порівняю
стосовно формули - upd http://replace.org.ua/post/79629/#p79629
все-одно дякую)) погрався з float))
знайшов таку функцію
%% max(N)
%% Create N processes then destroy them
%% See how much time this takes
max(N) ->
Max = erlang:system_info(process_limit),
io:format("*Maximum allowed processes:~p~n*" ,[Max]),
statistics(runtime),
statistics(wall_clock),
L = for(1, N, fun() -> spawn(fun() -> wait() end) end),
{_, Time1} = statistics(runtime),
{_, Time2} = statistics(wall_clock),
lists:foreach(fun(Pid) -> Pid ! die end, L),
U1 = Time1 * 1000 / N,
U2 = Time2 * 1000 / N,
io:format("*Process spawn time=~p (~p) microseconds~n*", [U1, U2]).
wait() ->
receive
die -> void
end.
for(N, N, F) -> [F()];
for(I, N, F) -> [F()|for(I+1, N, F)].
потикав-подивився як воно працює
2> ex:max(5).
*Maximum allowed processes:262144
**Process spawn time=0.0 (0.0) microseconds
*ok
3> ex:max(555).
*Maximum allowed processes:262144
**Process spawn time=0.0 (0.0) microseconds
*ok
4> ex:max(5555).
*Maximum allowed processes:262144
**Process spawn time=2.8802880288028803 (14.041404140414041) microseconds
*ok
5> ex:max(55555).
*Maximum allowed processes:262144
**Process spawn time=7.020070200702007 (8.136081360813607) microseconds
*ok
6> ex:max(5555).
*Maximum allowed processes:262144
**Process spawn time=8.28082808280828 (8.46084608460846) microseconds
*ok
7> ex:max(555).
*Maximum allowed processes:262144
**Process spawn time=0.0 (0.0) microseconds
*ok
8> ex:max(10000).
*Maximum allowed processes:262144
**Process spawn time=6.3 (6.3) microseconds
*ok
9> ex:max(100000).
*Maximum allowed processes:262144
**Process spawn time=4.53 (4.52) microseconds
*ok
задумався як воно працює -- виглядає так, наче спочатку "прогрівається"
цікаво - це результат того що ерланг зараз на вінді тицяю, чи й на лінуксі так же буде -- тобто це особливість ос чи віртуальної машини ерланга?
Дуже вдячний за дослідження, цікаво вийшло (тобно ще не вийшло, але все одно цікаво).
Маю припущення, що непомітність переваги цієї формули і проблеми з похибками були викликані із-за багаторазового використання функції pow.
Вибачте, я мав би зразу привести цю формулу до програмабельного вигляду.
Спочатку варто створити 2 константи:
GoldenRatio = 1.6180339887498948482045868343656381177399671246... (так званий золотий перетин),
в програмі його краще записати саме числом, а не формулою (1 + math:sqrt(5)) / 2;
і Sqrt5 = 2.23606797749978969640917366873127623547993424921... (math:sqrt(5)) теж числом.
Далі потрібно в якусь змінну записати результат виконання функції:
PowN = math:pow(GoldenRatio, N).
І тоді повертати потрібно щось таке:
(PowN + 1 / PowN) / Sqrt5.
Тому що
https://(агресор віджав цей домен)/images/2016/04/09/9bd4a1d7e74a1db81231222d9f825327.png
Теоретично, це має бути краще і по швидкості і по точності.
Ну, це якщо у Вас буде час.
Дуже вдячний за дослідження, цікаво вийшло (тобно ще не вийшло, але все одно цікаво).
Маю припущення, що непомітність переваги цієї формули і проблеми з похибками були викликані із-за багаторазового використання функції pow.
Вибачте, я мав би зразу привести цю формулу до програмабельного вигляду.
Спочатку варто створити 2 константи:
GoldenRatio = 1.6180339887498948482045868343656381177399671246... (так званий золотий перетин),
в програмі його краще записати саме числом, а не формулою (1 + math:sqrt(5)) / 2;
і Sqrt5 = 2.23606797749978969640917366873127623547993424921... (math:sqrt(5)) теж числом.
Далі потрібно в якусь змінну записати результат виконання функції:
PowN = math:pow(GoldenRatio, N).
І тоді повертати потрібно щось таке:
[code=erlang](PowN + 1 / PowN) / Sqrt5.[/code]
Тому що
https://(агресор віджав цей домен)/images/2016/04/09/9bd4a1d7e74a1db81231222d9f825327.png
Теоретично, це має бути краще і по швидкості і по точності.
Ну, це якщо у Вас буде час.
по точності - результати наведених прикладів-алгоритмів з int завжди будуть точніші за алгоритми з float, вірно?
це ж не суттєво -- чи sqrt, чи pow, чи 1.61803... -- це все float а не int повертає,
тому і похибки будуть
стосовно швидкості -- оцініть самі --
http://f1.s.сайт-злодій/15iw6PUn9.png
обчислення так само частина секунди як і N100
(мілісекунди не рахував - бо я - лінивець))
а от з float - сумніваюся що я зможу звести похибки до нуля взагалі при обчисленні N>100, навіть з будь-якою кількістю поправок (думаю що поправки лише на перших M чисел впливатимуть, а далі- знову похибки),
не впевнений що це взагалі можливо - порахувати на ерлангу з float так точно як з int
все ж, дякую за підказку стосовно помилки з pow - напевно ваше рішення справді допоможе з тією помилкою,
втім, float- залишиться float-ом
ерланг все ж не чисто програмістів рішення-продукт, це продукт інженерів у першу чергу
втім, якщо з float можуть бути проблеми, то з int у ерлангу як я бачу - жодних проблем, також відсутні проблеми з прийомо-передачею, робота з бінарними даними відносно простенька (відносно - бо ще досить часу пройде дпоки я повністю вїду)
----
на практиці у мене будуть числа, у тому числі й ділення, де буде виникати float, а це не бажано бо числа - дані про гроші- повинні бути точними
тут варіантів наче 2 --
1 - тримаємо суму балансу не гривні.копійки, а копійки --- не 11.25 грн, а 1125 коп
у копійках же і розраховуємо, після коми все при обчисленнях - закругляємо вниз,
помилка заокруглення невелика - ну все як у банках ой, я проговорився на чому ще банки нагрівають руки
(/, trunc,, ще можна float-результат у строку-список перевести і його уже опрацювати)
2 - трошки подібне до 1 - беремо окремо результат залишок від ділення, і цілочисельний результат (div, rem)
----
окремою спец-темою йде у ерлангу робота зі строками наступний великий спотикач який рве всі шаблони після незвичного синтаксису і концепцій роботи з памяттю і даними (після php-js-c-etc)
про це буде далі (і треба ж бо вїхати - бо треба динаміку віддавати - головну сайта --- зі статикою легше - nginx віддасть [знаю що трох тупо - для початку може бути поки немає повного контролю над ерлангом], а з апі як бути - уже майже догнав, ще трошечки)
народ, хто "мацав" ерланг, чи хотів би,
чи маєте якісь запитання, чи завдання ---
підкиньте будь-ласка
буду по мірі можливостей різні завдання розвязувати і ділитися по ерлангу -
і те що стосовно роботи, і просто для розвитку і розваги для
Ну якщо вже порівнювати ефективність алгоритмів для чисел Фібоначчі, то варто розглянути і інші, більш ефективні алгоритми, зокрема формулу, яка має виконуватися приблизно за час O(1).
Мені цікаво як в Erlang буде виглядати код для такої формули.
Варто зауважити, що це асимптотична формула - підходить для спечифічних задач з достатньо великим n
коментар до http://replace.org.ua/post/93079/#p93079 ---
в еліксирі немає модуля ets з його функціями, відповідно звертаємось до ерлангу
трошки теорії про ets(erlang term storage) та dets(disk-based erlang term storage) --
перше -- по-суті ерланговий аналог мемкеша(втім, це у моєму прикладі key-value -- в ets є і інші режими/налаштування) - тримати якісь значення в оперативці для швидкого доступу,
друге -- по суті те ж, проте зберігає дані на диск
https://elixirschool.com/ru/lessons/specifics/ets/
http://learnyousomeerlang.com/ets
http://erlang.org/doc/man/ets.html
http://erlang.org/doc/man/dets.html
https://replace.org.ua/post/79735/#p79735
жаль я тоді в 2016 не записав, яка то була версія ерланга )
отже, код функції той же (модуль назвав ex),
(l)ubuntu 16.04 lts, i3 2120 (4 * 3.3ГГц), erlang/otp 22
$ erl
Erlang/OTP 22 [erts-10.4] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
Eshell V10.4 (abort with ^G)
1>
1> c(ex).
{ok,ex}
2> ex:max(5).
*Maximum allowed processes:262144
**Process spawn time=200.0 (0.0) microseconds
*ok
3> ex:max(555).
*Maximum allowed processes:262144
**Process spawn time=1.8018018018018018 (1.8018018018018018) microseconds
*ok
4> ex:max(5555).
*Maximum allowed processes:262144
**Process spawn time=3.6003600360036003 (3.9603960396039604) microseconds
*ok
5> ex:max(55555).
*Maximum allowed processes:262144
**Process spawn time=3.006030060300603 (3.078030780307803) microseconds
*ok
6> ex:max(5555).
*Maximum allowed processes:262144
**Process spawn time=2.5202520252025202 (3.4203420342034203) microseconds
*ok
7> ex:max(555).
*Maximum allowed processes:262144
**Process spawn time=1.8018018018018018 (1.8018018018018018) microseconds
*ok
8> ex:max(10000).
*Maximum allowed processes:262144
**Process spawn time=4.2 (3.3) microseconds
*ok
9> ex:max(100000).
*Maximum allowed processes:262144
**Process spawn time=3.37 (3.21) microseconds
*ok
10> d1:max(100000).
*Maximum allowed processes:262144
**Process spawn time=2.85 (3.04) microseconds
*ok
11> d1:max(100000).
*Maximum allowed processes:262144
**Process spawn time=2.69 (2.82) microseconds
*ok
12> d1:max(100000).
*Maximum allowed processes:262144
**Process spawn time=2.68 (2.64) microseconds
*ok
13> d1:max(100000).
*Maximum allowed processes:262144
**Process spawn time=3.09 (2.84) microseconds
*ok
14> d1:max(100000).
*Maximum allowed processes:262144
**Process spawn time=3.0 (2.8) microseconds
*ok
15> d1:max(100000).
*Maximum allowed processes:262144
**Process spawn time=3.19 (3.09) microseconds
*ok
16> d1:max(100000).
*Maximum allowed processes:262144
**Process spawn time=3.26 (3.01) microseconds
*ok
однозачно, "прогрівається" --
спочатку 5555 процесів "шустрять довше", ніж далі 100 000 процесів
код прокоментую пізніше, коли перевірю з підняттям лімітів
в теорії, один легковісний "зелений потік"-процес віртуальної машини ерланга їсть ~2кб оперативки
на практиці, оці 100 000 потоків в даному прикладі їсть ~90мб - 190Мб
(хоча це не точно, це дивлячись що показує htop, дивлячись на всю зайняту пам'ять,
та і запущено в мене багато всього, тому думаю, що 90-100Мб то ерланг, а більше -- то щось інше хрумало)
далі буде
Сторінки 1
Для відправлення відповіді ви повинні увійти або зареєструватися