当前位置: 首页 > news >正文

网站建设经费申请报告宜昌seo优化服务

网站建设经费申请报告,宜昌seo优化服务,学室内设计要多久能学会,wordpress自定义输入目录 条款16#xff1a;谨记 80 - 20 法则条款17#xff1a;考虑使用lazy evaluation#xff08;缓式评估#xff09;条款18#xff1a;分期摊还预期的计算成本条款19#xff1a;了解临时对象来源条款20#xff1a;协助完成 “ 返回值优化 ”条款21#xff1a;利用重载… 目录 条款16谨记 80 - 20 法则条款17考虑使用lazy evaluation缓式评估条款18分期摊还预期的计算成本条款19了解临时对象来源条款20协助完成 “ 返回值优化 ”条款21利用重载技术避免隐式类型转换条款22考虑以操作符复合形式取代独身形式条款23考虑使用其他程序库条款24了解虚拟函数、多继承、虚基类和RTTI运行时类型辨识所需的代价 条款16谨记 80 - 20 法则 一个程序80%的资源用于20%的代码上。软件的整体性能几乎总是由构成要素的一小部分决定。你不仅需要找出造成问题的那一小段瓶颈所在还必须找出办法来改善位于瓶颈处的程序性能。大部分人采用“猜”的方法寻找瓶颈有一定道理更好地是借助一些程序分析器测量每段代码运行时间、消耗的内存空间、函数被调用的频繁度深究是否有临时对象产生等所在意的资源。借助可重现程序问题的数据帮忙解决问题。 条款17考虑使用lazy evaluation缓式评估 从效率的观点来看最佳的计算就是根本不计算关键在于拖延战术。当你使用了lazy evaluation后采用此种方法的类将推迟计算工作直到系统确实需要这些计算的结果。如果不需要结果将不用进行计算。区分读写读操作效率远高于写操作可能要先产生一个副本然后再赋值缓式取出当生产一个体积很大的对象时只生产对象的“外壳”不从磁盘读数据。当对象内的某个字段被需要了程序才从硬盘取回对应的字段数据。如下例其中指针可以被换成智能指针。 class LargeObject { public:LargeObject(ObjectID id); const string field1() const;int field2() const;double field3() const;const string field4() const;... private:ObjectID oid; mutable string *field1Value; //参见下面有关mutable int *field2Value; // mutable的讨论mutable double *field3Value;mutable string *field4Value;... }; LargeObject::LargeObject(ObjectID id) : oid(id), field1Value(0), field2Value(0), field3Value(0), ... {} const string LargeObject::field1() const {if (field1Value 0) {从数据库中为filed 1读取数据使field1Value 指向这个值;} return *field1Value; }当你试图在const成员函数里修改数据时编译器会出现问题。最好的方法是声明字段指针为mutable这表示在任何函数里它们都能被修改甚至在const成员函数里相当于告诉编译器“我知道我在干啥没事儿”。 如果不支持mutable可以用**“冒牌this”法产生一个非const指针指向this所指对象** const string LargeObject::field1() const {// 声明指针, fakeThis, 其与this指向同样的对象// 但是已经去掉了对象的常量属性LargeObject * const fakeThis const_castLargeObject* const(this); if (field1Value 0) {fakeThis-field1Value // 这赋值是正确的,the appropriate data // 因为fakeThis指向的from the database; //对象不是const} return *field1Value; }当有大量的运算时例如矩阵运算可用自定义的数据结构简单的表示两者关系但具体运算只在需要运算结果的时候进行计算且大多数时候只需要所有运算结果中的一部分。如果你的计算式必要的lazy evaluation并不会为你的程序节省任何工作或者时间反而会因为增加了新的数据结构而增加了时间和内存消耗。只有当你的程序被要求执行某些计算并且这些计算中有部分计算是可以避免的lazy evaluation才有效。 条款18分期摊还预期的计算成本 over-eager evaluation超前进度地做 “ 要求以外 ” 的更多工作。例如程序常常需要用到某种结果我们在得到新数据就计算一次结果进行保存这样真正要用的时候速度就会很快降低每次计算的平均成本。caching(缓存)那些已经被计算出来而以后还有可能需要的值 int findCubicleNumber(const string employeeName) {// 定义静态map存储 (employee name, cubicle number)// pairs. 这个 map 是local cache。typedef mapstring, int CubicleMap;static CubicleMap cubes; // try to find an entry for employeeName in the cache;// the STL iterator it will then point to the found// entry, if there is one (see Item 35 for details)CubicleMap::iterator it cubes.find(employeeName); if (it cubes.end()) {int cubicle the result of looking up employeeNames cubiclenumber in the database; cubes[employeeName] cubicle; // add the pair// (employeeName, cubicle)// to the cachereturn cubicle;}else {return (*it).second;} }这个方法是使用局部缓存用开销相对不大的内存中查询来替代开销较大的数据库查询。假如隔间号被不止一次地频繁需要在findCubicleNumber内使用缓存会减少返回隔间号的平均开销。 Prefetching(预提取)每次划分出必须比要求更多的资源。例如磁盘控制器从磁盘读取数据时经验显示如果需要一个地方的数据则很可能也需要它旁边的数据可一次性多读取些相邻的数据。动态数组会一次划分出比要求大小更大的数组保证数组表面上是动态可扩容的。更快的速度经常会消耗更多的内存。Cache运算结果需要更多的内存但是一旦需要被缓存的结果时就能减少需要重新生成的时间。Prefetch需要空间放置被prefetch的东西但是它减少了访问它们所需的时间。 条款19了解临时对象来源 临时对象产生的两种情况1为了使函数成功调用而进行隐式类型转换2函数返回对象时。函数参数隐式类型转换当传入函数的实参和形参类型不符且编译器可以进行隐式转换时编译器会以实参作为函数参数例如char所需类型string的构造函数构造函数stringchar的参数生成一个临时对象作为对应同类型的函数形参直到函数返回临时对象被销毁。 // 返回ch在str中出现的次数 size_t countChar(const string str, char ch); char buffer[MAX_STRING_LEN]; char c; // 读入到一个字符和字符串中用setw // 避免缓存溢出当读取一个字符串时 cin c setw(MAX_STRING_LEN) buffer; cout There are countChar(buffer, c) occurrences of the character c in buffer endl;仅当通过传值by value方式传递对象或传递常量引用reference-to-const参数时才会发生这些隐式类型转换。当传递一个非常量引用reference-to-non-const参数对象就不会发生。C语言禁止为非常量引用reference-to-non-const产生临时对象因为非常量引用表明可能修改引用对象如果允许隐式转换那么引用的就是临时对象而修改临时对象没有任何意义。对于大多数返回对象的函数来说难以被另一个函数替代从而没有办法避免构造和释放返回值对象。 条款20协助完成 “ 返回值优化 ” 采用返回指针的方法来避免临时对象生成可能会造成使用语法不自然c ab、资源泄漏忘记删除指针对象。 const Rational * operator*(const Rational lhs,const Rational rhs); Rational a 10; Rational b(1, 2); Rational c *(a * b); //你觉得这样很“正常”么采用返回引用的方法可能会造成返回的引用已经被销毁。 // 另一种危险的方法 (和不正确的)方法用来 // 避免返回对象 const Rational operator*(const Rational lhs,const Rational rhs) {Rational result(lhs.numerator() * rhs.numerator(),lhs.denominator() * rhs.denominator());return result;//返回时其指向的对象已经不存在了 }所以很大程度上无法避免使用by-value的方式返回对象。把你的努力引导到寻找减少返回对象的开销上来而不是去消除对象本身。可以使用某种特殊的写法来撰写函数使它在返回对象时能够让编译器自动进行优化消除临时对象成本。如下例产生一个临时对象然后将复制临时对象当作返回值。但是这样编译器就会被允许消除在operator*内的临时变量和operator*返回的临时变量。它们能在为目标c分配的内存里构造return表达式定义的对象只需要付出一个构造函数的成本。许多编译器都支持这一优化。 // 一种高效和正确的方法用来实现 // 返回对象的函数 const Rational operator*(const Rational lhs,const Rational rhs) {return Rational(lhs.numerator() * rhs.numerator(),lhs.denominator() * rhs.denominator()); } Rational a 10; Rational b(1, 2); Rational c a * b; // 在这里调用operator*条款21利用重载技术避免隐式类型转换 定义更多情况下的最佳匹配重载函数使得编译器选择最佳匹配的重载函数调用避免进行类型转换C规定每个 “ 重载操作符 ” 必须获得至少一个 “ 用户自定义类型 ” 的自变量。有时候增加一大堆重载函数不一定是件好事。 条款22考虑以操作符复合形式取代独身形式 确保操作符的复合形式x1与独身形式xx1之间的自然关系能够存在可以以前者为基础实现后者也便于维护。 class Rational { public:...Rational operator(const Rational rhs);Rational operator-(const Rational rhs); };// operator 根据operator实现; const Rational operator(const Rational lhs,const Rational rhs) {return Rational(lhs) rhs; } // operator- 根据 operator - 来实现 const Rational operator-(const Rational lhs,const Rational rhs) {return Rational(lhs) - rhs; }一般而言复合操作符比其独身形式效率更高因为独身形式要返回一个新对象从而在临时对象的构造和释放上有一些开销。然而复合操作符可以经过编译器优化后把结果直接写到左边的参数里因此不需要生成临时对象来容纳返回值。如果同时提供某个操作符的复合形式和独身形式便允许你的客户在效率和便利性之间做取舍。如下代码前者易撰写和维护后者效率更高。 Rational a, b, c, d, result; ... result a b c d; // 可能用了3个临时对象// 每个operator 调用使用1个 还是这样编写 result a; //不用临时对象 result b; //不用临时对象 result c; //不用临时对象 result d; //不用临时对象匿名对象比命名对象更容易清除因此当我们面对在命名对象和临时对象间进行选择时用临时对象更好一些。它使你耗费的开销不会比命名的对象还多。 //消耗一个匿名对象编译器有机会实现“返回值优化”把匿名对象直接写入接收函数返回对象的变量中 templateclass T const T operator(const T lhs, const T rhs) { return T(lhs) rhs; }//消耗一个命名对象result函数调用完毕后被析构没有机会消除这一消耗 templateclass T const T operator(const T lhs, const T rhs) {T result(lhs); // 拷贝lhs 到 result中return result rhs; // rhs与它相加并返回结果 }条款23考虑使用其他程序库 具有相同功能的不同的程序库在性能上采取不同的权衡措施所以一旦你找到软件的瓶颈你应该知道是否可能通过替换程序库来消除瓶颈。比如如果你的程序有I/O瓶颈你可以考虑用stdio替代iostream。 条款24了解虚拟函数、多继承、虚基类和RTTI运行时类型辨识所需的代价 一个虚函数表vtbl通常是一个函数指针数组或链表。在程序中的每个类只要声明了虚函数或继承了虚函数它就有自己的vtbl并且类中vtbl的项目是指向虚函数实现体的函数指针。每个类保留一份虚函数表。 class C1 { public:C1();virtual ~C1();virtual void f1();virtual int f2(char c) const;virtual void f3(const string s);void f4() const;... };class C2: public C1 { public:C2(); // 非虚函数virtual ~C2(); // 重定义函数virtual void f1(); // 重定义函数virtual void f5(char *str); // 新的虚函数... }; 虚函数指针vptr每个声明了虚函数的对象都带有它它是一个看不见的数据成员指向对应类的virtual table。 虚函数的三个成本每个类都有一个虚函数表、每个有虚函数的对象都有一个虚函数指针、放弃inlineinline在编译器将调用函数展开而虚函数在运行期才确定。 多继承往往导致虚基类的需求。因为继承会导致继承体系的所有成员被继承被复制对象体积迅速增大。虚基类可避免大量的复制现象不过虚基类也会增加一定的成本类对象中可能有多个虚指针隐藏指针。 运行期类型辨别RTTI类的相关信息存储在类型为type_info的对象里能通过使用typeid操作符访问一个类的type_info对象。RTTI耗费的空间是在每个类的vtbl中的占用的额外单元再加上存储type_info对象的空间。
http://www.dnsts.com.cn/news/90048.html

相关文章:

  • 江宁营销型网站建设网站如何兼容ie6
  • 淄博营销网站建设服务17网站一起做网店 发货慢
  • 哪个网站做贷款推广成品app
  • 手机网站模板制作工具服务类网站模板
  • 网站 开发逻辑网站制作标准
  • 网站开发与设计论文广州市天河区门户网站
  • 网站开发与设计课程时间购物网站建设模板下载
  • 海关企业信息查询网站html5英文视频网站建设
  • 如何做自己网站的访问记录辽宁建设厅规划设计网站
  • 法治建设优秀网站制作网站的流程
  • 如何做网站优惠券推广wordpress博客分享到朋友圈
  • 职业学校网站建设方案建设金融网站哪家好
  • 如何统计网站访问量做的网站如何防止怕爬虫
  • 自己网站的关键词怎么改小程序制作需要什么
  • 昆山玉山网站建设wordpress 订阅推送
  • 商城网站制作深圳网站制作淄博企业网站建设价格
  • 网站弹幕代码国外产品设计网
  • 以家乡为主题做网站游戏推广平台有哪些
  • 西安 做网站 499iis发布asp网站
  • 我国档案网站建设研究论文织梦建站系统教程
  • 河北沧州做网站的电话有什么网站建设类岗位
  • ih5做的网站怎么上传网站定制建设哪里好
  • 佛山企业网站建设多少钱wordpress默认邮件在哪里设置
  • 阿里云网站申请用途湖南人文科技学院排名
  • 长沙网站关键词排名国外h5制作网站
  • 百度给做网站吗传媒视频软件下载网站
  • 明快网站设计游戏云服务器租用
  • win7 asp.net网站架设游族网络公司最新消息
  • 成都网站平面设计python编程下载
  • 单页网站怎么做竞价专业品牌设计网站建设