实际上,当您将其开销与实际计算进行比较时,惰性工具包框架并不总是那么重要。
有很多方法。你可以使用Lazy,一个自我修改的 lambda 设置,一个布尔值或任何最适合你的工作流程的东西。
惰性评估工具包的开销仅在您进行一些重复计算时才需要考虑。
我的带有微基准的代码示例探讨了在循环中伴随的更昂贵操作的上下文中惰性计算的相对开销。
您可以看到,即使与相对芯片的有效负载操作一起使用,惰性工具包的开销也可以忽略不计。
void Main()
{
// If the payload is small, laziness toolkit is not neglectible
RunBenchmarks(i => i % 2 == 0, "Smaller payload");
// Even this small string manupulation neglects overhead of laziness toolkit
RunBenchmarks(i => i.ToString().Contains("5"), "Larger payload");
}
void RunBenchmarks(Func<int, bool> payload, string what)
{
Console.WriteLine(what);
var items = Enumerable.Range(0, 10000000).ToList();
Func<Func<int, bool>> createPredicateWithBoolean = () =>
{
bool computed = false;
return i => (computed || (computed = Compute())) && payload(i);
};
items.Count(createPredicateWithBoolean());
var sw = Stopwatch.StartNew();
Console.WriteLine(items.Count(createPredicateWithBoolean()));
sw.Stop();
Console.WriteLine("Elapsed using boolean: {0}", sw.ElapsedMilliseconds);
Func<Func<int, bool>> createPredicate = () =>
{
Func<int, bool> current = i =>
{
var computed2 = Compute();
current = j => computed2;
return computed2;
};
return i => current(i) && payload(i);
};
items.Count(createPredicate());
sw = Stopwatch.StartNew();
Console.WriteLine(items.Count(createPredicate()));
sw.Stop();
Console.WriteLine("Elapsed using smart predicate: {0}", sw.ElapsedMilliseconds);
Console.WriteLine();
}
bool Compute()
{
return true; // not important for the exploration
}
输出:
Smaller payload
5000000
Elapsed using boolean: 161
5000000
Elapsed using smart predicate: 182
Larger payload
5217031
Elapsed using boolean: 1980
5217031
Elapsed using smart predicate: 1994