C++ lazy evaluation(延迟计算或惰性求值)介绍
Posted fengbingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ lazy evaluation(延迟计算或惰性求值)介绍相关的知识,希望对你有一定的参考价值。
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;
执行结果如下图所示:
GitHub: https://github.com/fengbingchun/Messy_Test
以上是关于C++ lazy evaluation(延迟计算或惰性求值)介绍的主要内容,如果未能解决你的问题,请参考以下文章