Отказ от ответственности: я новичок в ReasonML.
Недавно я начал играть с ReasonML и заметил большую разницу в производительности по сравнению с ванильным JavaScript. Вот мои примеры простой функции решения головоломки (головоломка взята с: https://adventofcode.com/2015/day/1)
ReasonML
let head = str =>
switch (str) {
| "" => ""
| _ => String.sub(str, 0, 1)
};
let tail = str =>
switch (str) {
| "" => ""
| _ => String.sub(str, 1, String.length(str) - 1)
};
let rec stringToList = str =>
switch (str) {
| "" => []
| _ => [[head(str)], tail(str) |> stringToList] |> List.concat
};
let rec findFloor = code =>
switch (head(code)) {
| "" => 0
| "(" => 1 + findFloor(tail(code))
| ")" => (-1) + findFloor(tail(code))
| _ => 0
};
let findFloorFold = code => {
let calc = (a, b) =>
switch (b) {
| "" => a
| "(" => a + 1
| ")" => a - 1
| _ => a
};
code |> stringToList |> List.fold_left(calc, 0);
};
JavaScript
const solve = code => {
let level = 0;
for (let i = 0, l = code.length; i < l; i++) {
const el = code[i];
if (el === "(") {
++level;
continue;
}
if (el === ")") {
--level;
continue;
}
}
return level;
};
Результаты
- JavaScript: 5 мс
- ReasonML (рекурсивный): 470 мс
- ReasonML (нерекурсивный): 7185 мс
Ожидается ли это, или мои реализации функции ReasonML слишком медленные?
Заранее спасибо за разъяснения/предложения.
Следует признать, что второе решение (не rec) работает медленно из-за преобразования строки в массив, но это связано с тем, что в ReasonML строка не представлена списком символов.
String.iter
возвращает типunit
, поэтому я хочу иметь возможность накапливать результат операций (возможно, я неправильно понял ваше предложение ..). - person skay-   schedule 15.09.2018List.
методов и большого количества вызовов функций. - person Slai   schedule 15.09.2018stringToList
конверсия кажется ужасно неэффективной. Я не знаю ReasonML, я бы ожидал встроенной функции преобразования в стандартной библиотеке (или, по крайней мере,string
вarray(char)
). Хотя я бы выбралStr.split(regex "")
- person Bergi   schedule 15.09.2018