惰性目录迭代的好处是什么?
What is profits of lazy directory iteration?
我正在阅读 Phobos 文档并找到了完成 "lazily iterates a given directory" 的方法 dirEntries。但是我看不懂它真正的利润。
据我了解,惰性函数是指仅在需要时计算的函数。
我们看下一段代码:
auto files = dirEntries(...);
auto cnt = files.count;
foreach( file; files ) { }
dirEntries
会被调用多少次?一个或两个?请解释一下逻辑。
或者例如splitter
对我来说,这让代码更难理解。
如果使用得当,惰性计算的效率会更高。
假设你有一个有点昂贵的函数来做某事并且你将它应用到整个范围:
auto arr = iota(0, 100000); // a range of numbers from 0 to 100000
arr.map!(number => expensiveFunc(number))
.take(5)
.writeln;
如果 map 不是惰性的,它将对范围内的所有 100000 个项目执行 expensiveFunc
,然后弹出其中的前 5 个。
但是因为 map 是惰性的,expensiveFunc 只会为实际从范围中弹出的 5 个项目调用。
与拆分器类似,假设您有一个包含一些数据的 csv 字符串,您希望继续对值求和,直到遇到负值。
string csvStr = "100,50,-1,1000,10,24,51"
int sum;
foreach(val; csvStr.splitter(",")){
immutable asNumber = val.to!int;
if(asNumber < 0) break;
sum += asNumber;
}
writeln(sum);
上面只会做 3 次昂贵的 'splitting' 工作,因为拆分器是懒惰的,我们只需要读取 3 个项目。使我们不必一直拆分 csvStr 直到最后,即使我们不需要它们。
所以,综上所述,惰性求值的好处是,只有需要要做的工作才真正完成。
我正在阅读 Phobos 文档并找到了完成 "lazily iterates a given directory" 的方法 dirEntries。但是我看不懂它真正的利润。
据我了解,惰性函数是指仅在需要时计算的函数。
我们看下一段代码:
auto files = dirEntries(...);
auto cnt = files.count;
foreach( file; files ) { }
dirEntries
会被调用多少次?一个或两个?请解释一下逻辑。
或者例如splitter
对我来说,这让代码更难理解。
如果使用得当,惰性计算的效率会更高。
假设你有一个有点昂贵的函数来做某事并且你将它应用到整个范围:
auto arr = iota(0, 100000); // a range of numbers from 0 to 100000
arr.map!(number => expensiveFunc(number))
.take(5)
.writeln;
如果 map 不是惰性的,它将对范围内的所有 100000 个项目执行 expensiveFunc
,然后弹出其中的前 5 个。
但是因为 map 是惰性的,expensiveFunc 只会为实际从范围中弹出的 5 个项目调用。
与拆分器类似,假设您有一个包含一些数据的 csv 字符串,您希望继续对值求和,直到遇到负值。
string csvStr = "100,50,-1,1000,10,24,51"
int sum;
foreach(val; csvStr.splitter(",")){
immutable asNumber = val.to!int;
if(asNumber < 0) break;
sum += asNumber;
}
writeln(sum);
上面只会做 3 次昂贵的 'splitting' 工作,因为拆分器是懒惰的,我们只需要读取 3 个项目。使我们不必一直拆分 csvStr 直到最后,即使我们不需要它们。
所以,综上所述,惰性求值的好处是,只有需要要做的工作才真正完成。