即時計算と遅延計算
50503 ワード
関連コンテンツ
反復器とforの関係
ファンクションプログラミング実装
range/ゆったりrange+take
総クリーンアップコード
const go = (...list) => reduce((a, f) => f(a), list);
const curry = (f) => (a, ..._) =>
_.length ? f(a, ..._) : (..._) => f(a, ..._);
const reduce = curry((f, acc, iter) => {
if (!iter) {
iter = acc[Symbol.iterator]();
acc = iter.next().value;
}
for (const a of iter) {
acc = f(acc, a);
}
return acc;
});
const map = curry((f, iter) => {
let res = [];
for (const a of iter) {
res.push(f(a));
}
return res;
});
const filter = curry((f, iter) => {
let res = [];
for (const a of iter) {
if (f(a)) res.push(a);
}
return res;
});
const range = (l) => {
let i = -1;
let res = [];
while (++i < l) {
res.push(i);
}
return res;
};
range(4);
//L관련
const L = {};
L.range = function* (l) {
let i = -1;
while (++i < l) {
yield i;
}
};
L.map = curry(function* (f, iter) {
for (const a of iter) yield f(a);
});
L.filter = curry(function* (f, iter) {
for (const a of iter) if (f(a)) yield a;
});
const take = curry((l, iter) => {
let res = [];
for (const a of iter) {
res.push(a);
if (res.length == l) return res;
}
return res;
});
const takeAll = take(Infinity);
go(
range(10),
map((n) => n + 10),
filter((n) => n % 2),
take(2),
console.log
);
go(
L.range(10),
L.map((n) => n + 10),
L.filter((n) => n % 2),
take(2),
console.log
);
高速計算(発電機X使用)と低速計算(発電機O使用)
range,map,filterを用いた高速計算とl.range,l.map,l.filterを用いた遅い計算では,進行中にも差がある.
クイック計算はrange->map->filter->takeの順に並べ替えの進捗を処理します.
スローコンピューティングはtake->filter->map->range->map->filter->takeの繰り返しを処理します.
どちらがいいですか。
配列が大きい場合は、高速計算ではすべての配列を作成し、その配列を処理する必要があります.
しかし,緩やかな計算では対応する値を処理する必要があり,配列がすべて生成されなくても,=>すなわち,要求を満たすと,まずその内容を終了する効率が高くなる.
こうりつしけん
console.time();
go(
range(10000000),
map((n) => n + 10),
filter((n) => n % 2),
take(2),
console.log
);
console.timeEnd();
console.time();
go(
L.range(10000000),
L.map((n) => n + 10),
L.filter((n) => n % 2),
take(2),
console.log
);
console.timeEnd();
[ 11, 13 ]
default: 1.503s
[ 11, 13 ]
default: 0.228ms
大きく並べば並べるほど、差が大きくなります.このハーモニーなら?遅延と即時計算の組合せ
let users = [
{
name: "a",
age: 21,
family: [
{ name: "a1", age: 53 },
{ name: "a2", age: 47 },
{ name: "a3", age: 16 },
{ name: "a4", age: 15 },
],
},
{
name: "b",
age: 21,
family: [
{ name: "b1", age: 58 },
{ name: "b2", age: 51 },
{ name: "b3", age: 19 },
{ name: "b4", age: 22 },
],
},
{
name: "c",
age: 21,
family: [
{ name: "c1", age: 64 },
{ name: "c2", age: 62 },
],
},
{
name: "d",
age: 21,
family: [
{ name: "d1", age: 42 },
{ name: "d2", age: 42 },
{ name: "d3", age: 11 },
{ name: "d4", age: 7 },
],
},
];
const curry = (f) => (a, ..._) =>
_.length ? f(a, ..._) : (..._) => f(a, ..._);
const reduce = curry((f, acc, iter) => {
if (!iter) {
iter = acc[Symbol.iterator]();
acc = iter.next().value;
}
for (const a of iter) {
acc = f(acc, a);
}
return acc;
});
const go = (...list) => reduce((a, f) => f(a), list);
const pipe = (...fs) => (a) => go(a, ...fs);
let L = {};
const isIterable = (a) => a && a[Symbol.iterator];
L.flatten = function* (iter) {
for (const a of iter) {
if (isIterable(a)) for (const b of a) yield b;
else yield a;
}
};
L.map = curry(function* (f, iter) {
console.log(iter, "L.map Iter");
for (const a of iter) {
console.log(a, "L.map a");
yield f(a);
}
});
L.map1 = curry(function* (f, iter) {
console.log(iter, "L.map1 Iter");
for (const a of iter) {
console.log(a, "L.map1 a");
yield f(a);
}
});
L.filter = curry(function* (f, iter) {
for (const a of iter)
if (f(a)) {
console.log(a, "L.Filter a");
yield a;
}
});
const filter = curry((f, iter) => {
console.log(iter, "filter Iter");
let res = [];
for (const a of iter) {
if (f(a)) res.push(a);
}
console.log(res, "Filter");
return res;
});
const take = curry((l, iter) => {
let res = [];
for (const a of iter) {
res.push(a);
if (res.length == l) return res;
}
return res;
});
const add = (a, b) => a + b;
go(
users,
L.map((u) => u.family),
L.flatten,
L.filter((u) => u.age < 20),
L.map1((u) => u.age),
take(3),
reduce(add),
console.log
);
go(
users,
L.map((u) => u.family),
L.flatten,
filter((u) => u.age < 20),
L.map1((u) => u.age),
take(3),
reduce(add),
console.log
);
最初のgoはLに接続されています2番目のgoはLの間にフィルタがあります.
恐らくそうでしょう.すなわち、filterはすべてのa b c dを遍歴する.
L.filterは毎回必要な部分が1つしか必要ないようで、巡回検索を行います.
Reference
この問題について(即時計算と遅延計算), 我々は、より多くの情報をここで見つけました https://velog.io/@khw970421/바로-계산과-지연-계산テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol