** C++****中的lazy evaluation or call-by-need(****延迟计算或按需调用)**是一种求值策略,其中表达式在第一次使用之前不求值,即将求值推迟到真正需要时。
** **为一个最终可能不需要的计算付出性能代价显然不是明智之举。然而在复杂的代码中这种情况比比皆是。我们不应该执行"只在某种情况下"才需要的昂贵计算,而应该只在必要的时候执行昂贵计算。这通常意味着把计算推迟到真正需要的时候才进行,因此称之为延迟计算或惰性求值。在C++中,对象的定义会调用构造函数和析构函数,这可能是高成本的,因为它导致了立即计算----而这正是我们所要避免的。延迟计算原则建议我们推迟对象的定义,直到要使用该对象时再定义。为不一定用到的构造函数和析构函数付出代价是没有意义的。不仅应该将对象的创建推迟至合适的位置,而且应该直到具备了一个有效创建操作所必需的全部条件后,再创建对象。
** **当你使用了lazy evaluation后,采用此种方法的类将推迟计算工作直到系统需要这些计算的结果。如果不需要结果,将不用进行计算。
** **在某些情况下要求软件进行原来可以避免的计算,这时lazy evaluation才是有用的。
** **下面是两个采用lazy evaluation的测试代码段:
1.通过引用计数减少不必要的拷贝:
int test_evaluation_1()
{
// 引用计数: 除非你确实需要,否则不去为任何东西制作拷贝.我们应该是lazy的,只要有可能就共享使用其它值
std::string str1 = "hello";
std::string str2 = str1; // str2和str1指向同一块内存地址
fprintf(stdout, "pointer: str1: %p, str2: %p\n", // pointer: str1: 0x2061208, str2: 0x2061208
static_cast<void*>(const_cast<char*>(str1.c_str())), static_cast<void*>(const_cast<char*>(str2.c_str())));
str2 = "beijing"; // str2被重新赋值后,str2和str1不在指向同一块内存地址
fprintf(stdout, "pointer: str1: %p, str2: %p\n", // pointer: str1: 0x2061208, str2: 0x2061648
static_cast<void*>(const_cast<char*>(str1.c_str())), static_cast<void*>(const_cast<char*>(str2.c_str())));
return 0;
}
** **2.矩阵运算中,在真正使用时才做运算,通过运算符重载实现:
using matrix = std::array<int, 2>;
// write this proxy
struct matrix_add {
matrix_add(const matrix& a, const matrix& b) : a_(a), b_(b) { fprintf(stdout, "do nothing\n"); }
// an implicit conversion operator from matrix_add to plain matrix
// the evaluation takes place only when the final result is assigned to a matrix instance
operator matrix() const {
fprintf(stdout, "add operation\n");
matrix result;
for (int i = 0; i < 2; ++i)
result[i] = a_[i] + b_[i];
return result;
}
// calculate one element out of a matrix sum
// it's of course wasteful to add the whole matrices
int operator ()(unsigned int index) const {
fprintf(stdout, "calculate *just one* element\n");
return a_[index] + b_[index];
}
private:
const matrix& a_, b_;
};
// to make this function lazy, it's enough to return a proxy instead of the actual result
matrix_add operator + (const matrix& a, const matrix& b)
{
return matrix_add(a, b);
}
int test_evaluation_2()
{
// reference: https://stackoverflow.com/questions/414243/lazy-evaluation-in-c
// 矩阵计算: 主要机制是运算符重载
matrix mat1 = {2, 3}, mat2 = {7, 8};
auto ret = mat1 + mat2;
fprintf(stdout, "... ...\n");
matrix mat3(ret); // implicit conversion from matrix_add to matrix
fprintf(stdout, "one element sum: %d\n", ret(1));
return 0;
}
执行结果如下图所示:
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/fengbingchun/article/details/125824232
内容来源于网络,如有侵权,请联系作者删除!