免责声明: 我是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函数实现得太慢了?
感谢您提供澄清/建议。
不可否认,第二个解决方案(非递归)由于字符串到数组的转换而变慢,但这是因为在ReasonML中,字符串不是由字符列表表示的。
String.iter
返回unit
类型,所以我无法累加操作的结果(也许我误解了你的建议..)。 - skay-List.
方法和许多函数调用的开销。 - SlaistringToList
转换看起来非常低效。我不了解 ReasonML,但我希望标准库中有本地转换函数(或至少是string
到array(char)
的函数)。我会选择Str.split(regex "")
。 - Bergi