是否值得惯用编程?一个 ES6 例子
Is it worth idiomatic programming? An ES6 example
编程就是决定如何实现任何一段代码。根据这些决定,代码将或多或少具有可读性、高效性、复杂性等。一个常见的决定也是或多或少地符合习惯,即使用特定的语句或您的编程语言或范例。
作为概念证明,我在 Javascript 中开发了两个代码片段来分析性能。目标是生成 tagA|tagB|tagC
形式的字符串,其中 tagX
的数量是随机的,后缀 A
、B
、C
是随机整数。而且,tagX
不能重复
第一个实现更为地道,而第二个则更为传统。接下来是每一个的代码片段:
惯用语:
performance.mark('A');
let tags = new Set(Array.from({length: tagCount}, () => Math.floor(Math.random() * 10)));
tags = Array.from(tags).map(x => `tag${x}`).join('|');
performance.mark('B');
传统
performance.mark('C');
let tagset = new Set();
let tagstr = "";
for (let tag=0; tag<tagCount; tag++) {
tagset.add(Math.floor(Math.random() * 10));
}
tagset.forEach((tag) => {
tagstr += 'tag' + tag + '|'
});
tagstr = tagstr.slice(0, -1);
performance.mark('D');
为了衡量性能,我使用了 Performance Timing API
结果有点令人惊讶,至少对我来说是这样。请注意传统方法比另一种方法效率高得多。
Idiomatic: 0.436535
Traditional: 0.048177
我重复了几次实验,结果都差不多
地道的方式看起来很酷而且更短,但效率较低且难以阅读。
你怎么看?是否值得使用惯用编程而不是传统编程?是否有一个普遍的答案,或者它在很大程度上取决于每个案例?
代码的可读性和复杂性如何?
已编辑:tagX
不能重复。
已编辑:仅供参考,我已将完整代码上传至Github:https://github.com/aecostas/benchmark-js-looping
Idiomatic way looks pretty cool and shorter, but it is less efficient and hard to read.
如果熟悉该语言的人觉得难以阅读,则它不是“地道的”。 (你可能会按照这个词的一个定义——“使用许多惯用语”——但这并不是人们提到惯用代码时的意思,尽管 Array.from({length}, fn)
确实是一个 idiom¹ 用于根据 JavaScript 中的函数填充数组。更确切地说,它是按照语言用户期望的方式编写的代码。)您可以通过命名一些东西来更接近它:
const tagNumbers = Array.from(
{length: tagCount},
() => Math.floor(Math.random() * 10),
);
const uniqueTagNumbers = Array.from(new Set(tagNumbers));
const tagString =
uniqueTagNumbers
.map(n => 'tag' + n)
.join('|');
并利用实践中存在的效用函数类型:
import generate from '…';
import unique from '…';
const getRandomTag = () =>
Math.random() * 10 | 0;
const tags =
generate(tagCount, getRandomTag);
const tagString =
unique(tags)
.map(n => 'tag' + n)
.join('|');
尽管如此,您只能使用玩具示例。
至于性能:并非所有内容都必须进行微优化。你这里的两个例子有相同的渐近时间和 space 复杂度,这对很多情况来说已经足够了。你用 JavaScript 写作是因为它的语言特性可以让你以性能为代价更好地表达自己²,毕竟。当涉及到优化时,您可能希望编写更准确的基准(这在 Node 中非常困难!)——例如尝试重新排序这些测量结果。
¹ 在某种意义上,作为一种语言用户知道的表达方式,表达方式本身并没有清楚地传达这一点。
² 或者因为其他人或其他一些人认为,现在你被困在他们的代码上,或者可能是出于某种原因而不是表现力本身,或者前面提到的人在同一个boat³, …
³ 哦嘿一个成语
编程就是决定如何实现任何一段代码。根据这些决定,代码将或多或少具有可读性、高效性、复杂性等。一个常见的决定也是或多或少地符合习惯,即使用特定的语句或您的编程语言或范例。
作为概念证明,我在 Javascript 中开发了两个代码片段来分析性能。目标是生成 tagA|tagB|tagC
形式的字符串,其中 tagX
的数量是随机的,后缀 A
、B
、C
是随机整数。而且,tagX
不能重复
第一个实现更为地道,而第二个则更为传统。接下来是每一个的代码片段:
惯用语:
performance.mark('A');
let tags = new Set(Array.from({length: tagCount}, () => Math.floor(Math.random() * 10)));
tags = Array.from(tags).map(x => `tag${x}`).join('|');
performance.mark('B');
传统
performance.mark('C');
let tagset = new Set();
let tagstr = "";
for (let tag=0; tag<tagCount; tag++) {
tagset.add(Math.floor(Math.random() * 10));
}
tagset.forEach((tag) => {
tagstr += 'tag' + tag + '|'
});
tagstr = tagstr.slice(0, -1);
performance.mark('D');
为了衡量性能,我使用了 Performance Timing API
结果有点令人惊讶,至少对我来说是这样。请注意传统方法比另一种方法效率高得多。
Idiomatic: 0.436535
Traditional: 0.048177
我重复了几次实验,结果都差不多
地道的方式看起来很酷而且更短,但效率较低且难以阅读。
你怎么看?是否值得使用惯用编程而不是传统编程?是否有一个普遍的答案,或者它在很大程度上取决于每个案例?
代码的可读性和复杂性如何?
已编辑:tagX
不能重复。
已编辑:仅供参考,我已将完整代码上传至Github:https://github.com/aecostas/benchmark-js-looping
Idiomatic way looks pretty cool and shorter, but it is less efficient and hard to read.
如果熟悉该语言的人觉得难以阅读,则它不是“地道的”。 (你可能会按照这个词的一个定义——“使用许多惯用语”——但这并不是人们提到惯用代码时的意思,尽管 Array.from({length}, fn)
确实是一个 idiom¹ 用于根据 JavaScript 中的函数填充数组。更确切地说,它是按照语言用户期望的方式编写的代码。)您可以通过命名一些东西来更接近它:
const tagNumbers = Array.from(
{length: tagCount},
() => Math.floor(Math.random() * 10),
);
const uniqueTagNumbers = Array.from(new Set(tagNumbers));
const tagString =
uniqueTagNumbers
.map(n => 'tag' + n)
.join('|');
并利用实践中存在的效用函数类型:
import generate from '…';
import unique from '…';
const getRandomTag = () =>
Math.random() * 10 | 0;
const tags =
generate(tagCount, getRandomTag);
const tagString =
unique(tags)
.map(n => 'tag' + n)
.join('|');
尽管如此,您只能使用玩具示例。
至于性能:并非所有内容都必须进行微优化。你这里的两个例子有相同的渐近时间和 space 复杂度,这对很多情况来说已经足够了。你用 JavaScript 写作是因为它的语言特性可以让你以性能为代价更好地表达自己²,毕竟。当涉及到优化时,您可能希望编写更准确的基准(这在 Node 中非常困难!)——例如尝试重新排序这些测量结果。
¹ 在某种意义上,作为一种语言用户知道的表达方式,表达方式本身并没有清楚地传达这一点。
² 或者因为其他人或其他一些人认为,现在你被困在他们的代码上,或者可能是出于某种原因而不是表现力本身,或者前面提到的人在同一个boat³, …
³ 哦嘿一个成语