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: 0x2061208static_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: 0x2061648static_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 instanceoperator 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 matricesint 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 matrixfprintf(stdout, "one element sum: %d\n", ret(1));return 0;
}

执行结果如下图所示:

GitHub: https://github.com/fengbingchun/Messy_Test

C++ lazy evaluation(延迟计算或惰性求值)介绍相关推荐

  1. python中关系运算符惰性求值,lazy.js 惰性求值实现分析

    背景:惰性求值? 来看一个 lazy.js 主页提供的示例: var people = getBigArrayOfPeople(); var results = _.chain(people) .pl ...

  2. java惰性计算原理_利用 Lambda 表达式实现 Java 中的惰性求值

    Java 中惰性求值的潜能,完全被忽视了(在语言层面上,它仅被用来实现 短路求值 ).更先进的语言,如 Scala,区分了传值调用与传名调用,或者引入了 lazy 这样的关键字. 尽管 Java 8 ...

  3. 惰性求值——lodash源码解读

    前言 lodash受欢迎的一个原因,是其优异的计算性能.而其性能能有这么突出的表现,很大部分就来源于其使用的算法--惰性求值. 本文将讲述lodash源码中,惰性求值的原理和实现. 一.惰性求值的原理 ...

  4. python中and和or的惰性求值特点_惰性求值和yield-Python

    惰性求值 惰性求值(Lazy evaluation)是在需要时才进行求值的计算方式.表达式不在它被绑定到变量之后就立即求值,而是在该值被取用的时候求值. 除可以得到性能的提升(更小的内存占用)外,惰性 ...

  5. python惰性求值例子_惰性求值和yield-Python

    惰性求值 惰性求值(Lazy evaluation)是在需要时才进行求值的计算方式.表达式不在它被绑定到变量之后就立即求值,而是在该值被取用的时候求值. 除可以得到性能的提升(更小的内存占用)外,惰性 ...

  6. 惰性求值 php,惰性求值——lodash源码解读

    前言 lodash受欢迎的一个原因,是其优异的计算性能.而其性能能有这么突出的表现,很大部分就来源于其使用的算法--惰性求值. 本文将讲述lodash源码中,惰性求值的原理和实现. 一.惰性求值的原理 ...

  7. 惰性求值 php,使用 JavaScript 进行函数式编程 (一) 翻译

    编程范式 编程范式是一个由思考问题以及实现问题愿景的工具组成的框架.很多现代语言都是聚范式(或者说多重范式): 他们支持很多不同的编程范式,比如面向对象,元程序设计,泛函,面向过程,等等. 函数式编程 ...

  8. 惰性求值 php,详细介绍C#函数式编程的示例代码

    public double MemoryUtilization() { //计算目前内存使用率 var pcInfo = new ComputerInfo(); var usedMem = pcInf ...

  9. 让Python中类的属性具有惰性求值的能力

    起步 我们希望将一个只读的属性定义为 property 属性方法,只有在访问它时才进行计算,但是,又希望把计算出的值缓存起来,不要每次访问它时都重新计算. 解决方案 定义一个惰性属性最有效的方法就是利 ...

  10. python惰性求值的特点_C#教程之C#函数式编程中的惰性求值详解

    https://www.xin3721.com/eschool/python.html 惰性求值 在开始介绍今天要讲的知识之前,我们想要理解严格求值策略和非严格求值策略之间的区别,这样我们才能够深有体 ...

最新文章

  1. 基类的析构函数为什么要设置成virtual
  2. 惨烈!程序员放弃了 Python!?发生了啥?
  3. 【响应式Web前端设计】:link、:hover、:active和:visited的区别
  4. 中国科学院空天信息研究院苏州分院面试——总结
  5. 为docker设置国内镜像【转】
  6. java8中-_java8中的Stream
  7. 我是怎么用机器学习技术找到女票的
  8. python关键词提取源码_Python 结巴分词 关键词抽取分析
  9. 进程控制块PCB(进程描述符)
  10. java8源代码_java8 源码解读
  11. python 装饰器(可以接收多个值)
  12. 【BZOJ4518】征途,斜率优化DP
  13. PostgreSQL Oracle 兼容性之 - rowid (CREATE TABLE WITH OIDS)
  14. 云时代的“双态IT”运维思路
  15. aht10温湿度传感器特点及使用介绍
  16. ANSYS APDL学习(12):如何将ansys求解后的数据(点位移/应力/应变等)导出到txt文件
  17. Spring Boot开发登录、退出功能
  18. python谷歌小恐龙,这还是你断网时的样子嘛~
  19. 全国大学生数学建模大赛入门1——赛前准备及注意事项
  20. 计算机内存采用什么存储模式,计算机内存模型

热门文章

  1. PS 如何制作Vista的毛玻璃效果
  2. Unity应该怎样学习
  3. 异常:could not initialize proxy - the owning Session was closed
  4. 工业机器人产业链展板_赵德明调研六大新产业十大产业链发展情况
  5. testerhome职业辅导沙龙
  6. 内网渗透系列:隐匿攻击方法
  7. 通用虚拟平台virt
  8. 洛谷1315 观光公交(贪心)
  9. SCM-PEG2000-Maleimide,Mal-PEG2000-Succinimidyl Carboxymethyl Ester
  10. 在SVG中旋转图形,需要设置各个图形的旋转中心点