Javascript 高效获取二维数组中某个值的行号
Javascript efficiently get row number of a value in two dimensional array
return 二维数组中值的行号的最有效方法是什么?例如,我可以执行以下操作。我可以使用 map and/or 过滤器而不是迭代来做到这一点吗?
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
for (let i = 0; i < array2d.length; i++) {
if (array2d[i].indexOf(value) > -1) {
return i;
}
}
return -1;
}
您可以这样使用 Array.prototype.findIndex
with Array.prototype.includes
:
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
for (let i = 0; i < array2d.length; i++) {
if (array2d[i].indexOf(value) > -1) {
return i;
}
}
return -1;
}
const now = performance.now();
console.log(getRow());
console.log(performance.now() - now);
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
return array2d.findIndex(x => x.includes(value));
}
const now = performance.now();
console.log(getRow());
console.log(performance.now() - now);
在此处发布 findIndex
的示例,回调速度比 for loop
..
我的结果:
for 循环 = 11.020000092685223
更快。
带回调的 findIndex = 12.699999962933362
较慢。
故事的士气,如果表演很关键,总是考验。浏览器有一些非常聪明/复杂的优化。例如,@GuerricP 发布的基准仅进行了简单的 属性 比较,而 V8 引擎可能会检测到这一点。放个更复杂的includes
进去,就是另外一回事了
同样出于上述原因,您永远不应该预先优化 JS,只有在您认为有性能问题需要解决时才进行优化。
同样使事情复杂化的是不同的浏览器/OS可能会给出不同的结果。我的测试 Linux / Chrome.
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
for (let i = 0; i < array2d.length; i++) if (array2d[i].indexOf(value) > -1) return i;
return -1;
}
const now = performance.now();
for (let l = 0; l < 1000000; l += 1)
getRow();
console.log(performance.now() - now);
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
return array2d.findIndex(x => x.includes(value));
}
const now = performance.now();
for (let l = 0; l < 1000000; l += 1)
getRow();
console.log(performance.now() - now);
有了节点,可以把数组分成多个
子数组并使用异步 运行 并行搜索:
下面的脚本使用了两个线程,给你一半的时间。
async function aGetRow(d, v) {
let half = Math.floor(d.length / 2);
let remain = d.length - half
let r = await Promise.all([
getRow(d.slice(0, half), v),
getRow(d.slice(half, remain), v),
]);
if (r[0] != -1) {
return r[0];
}
if (r[1] != -1) {
return r[1];
}
return -1;
}
需要注意的是,NodeJS默认在线程池中有4个线程。如果拆分数组多于线程,则不会获得性能提升。
编辑:对于对 NodeJS 线程和事件循环的细节感兴趣的人,我强烈推荐这个视频:https://youtu.be/zphcsoSJMvM
return 二维数组中值的行号的最有效方法是什么?例如,我可以执行以下操作。我可以使用 map and/or 过滤器而不是迭代来做到这一点吗?
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
for (let i = 0; i < array2d.length; i++) {
if (array2d[i].indexOf(value) > -1) {
return i;
}
}
return -1;
}
您可以这样使用 Array.prototype.findIndex
with Array.prototype.includes
:
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
for (let i = 0; i < array2d.length; i++) {
if (array2d[i].indexOf(value) > -1) {
return i;
}
}
return -1;
}
const now = performance.now();
console.log(getRow());
console.log(performance.now() - now);
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
return array2d.findIndex(x => x.includes(value));
}
const now = performance.now();
console.log(getRow());
console.log(performance.now() - now);
在此处发布 findIndex
的示例,回调速度比 for loop
..
我的结果:
for 循环 = 11.020000092685223
更快。
带回调的 findIndex = 12.699999962933362
较慢。
故事的士气,如果表演很关键,总是考验。浏览器有一些非常聪明/复杂的优化。例如,@GuerricP 发布的基准仅进行了简单的 属性 比较,而 V8 引擎可能会检测到这一点。放个更复杂的includes
进去,就是另外一回事了
同样出于上述原因,您永远不应该预先优化 JS,只有在您认为有性能问题需要解决时才进行优化。
同样使事情复杂化的是不同的浏览器/OS可能会给出不同的结果。我的测试 Linux / Chrome.
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
for (let i = 0; i < array2d.length; i++) if (array2d[i].indexOf(value) > -1) return i;
return -1;
}
const now = performance.now();
for (let l = 0; l < 1000000; l += 1)
getRow();
console.log(performance.now() - now);
function getRow(array2d = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], value = 'g') {
return array2d.findIndex(x => x.includes(value));
}
const now = performance.now();
for (let l = 0; l < 1000000; l += 1)
getRow();
console.log(performance.now() - now);
有了节点,可以把数组分成多个 子数组并使用异步 运行 并行搜索:
下面的脚本使用了两个线程,给你一半的时间。
async function aGetRow(d, v) {
let half = Math.floor(d.length / 2);
let remain = d.length - half
let r = await Promise.all([
getRow(d.slice(0, half), v),
getRow(d.slice(half, remain), v),
]);
if (r[0] != -1) {
return r[0];
}
if (r[1] != -1) {
return r[1];
}
return -1;
}
需要注意的是,NodeJS默认在线程池中有4个线程。如果拆分数组多于线程,则不会获得性能提升。
编辑:对于对 NodeJS 线程和事件循环的细节感兴趣的人,我强烈推荐这个视频:https://youtu.be/zphcsoSJMvM