- 浏览: 369965 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (335)
- C++ (190)
- 设计模式 (43)
- 数据库技术 (5)
- 网络编程 (11)
- 自动化测试 (6)
- Linux (13)
- OpenSSL (10)
- MS Crypt API (5)
- SCM (2)
- English (4)
- Android (10)
- EMV规范 (1)
- Saturn Platform (0)
- C (10)
- SQL (2)
- ASP.NET (3)
- 英语口语学习 (3)
- 调试工具 (21)
- 编译技术 (5)
- UML (1)
- 项目管理 (5)
- 敏捷开发 (2)
- Http Server (6)
- 代码审查、代码分析 (5)
- 面试基础 (10)
- 重点知识 (16)
- STL (6)
- Efficient C++资料 (8)
- 数据结构和算法 (7)
- 读书笔记 (0)
- 开源项目 (4)
- 多线程 (2)
- Console App (6)
- 个人开源项目 (4)
- IBM DevelopWorks (4)
- Java (16)
- 内存泄漏相关调试和检测 (13)
- 软件测试相关技术 (2)
- C# (11)
- Apple Related (1)
- 软件测试和管理 (2)
- EMV (1)
- Python (1)
- Node.js (6)
- JavaScript (5)
- VUE (1)
- Frontend (1)
- Backend (4)
- RESTful API (3)
- Firebase (3)
最新评论
-
u013189503:
来个密码吧
[C++][Logging] 项目中写日志模块的实现 -
wyf_vc:
来个密码啊!!
[C++][Logging] 项目中写日志模块的实现
转自
http://blog.chinaunix.net/uid-25872711-id-3013832.html
Charpter 1 The tracing war story
很多时候,为了方便查找bug,会使用trace。比如用如下方式:
这样的方式不错,但是问题是:每次TRACE宏的开头都要重新编译代码。想到用如下方式避免这一问题:
加入一个traceIsActive变量来控制log开关,因为写log开销最大,这样看上去也算可行。下面看,假设有如下调用:
即使,traceIsActive为false,上面的调用还是会产生如下开销:
1) 创建一个临时string变量保存“x=”
2) 调用itoa()函数
3) 创建一个临时string变量保存itoa(x)返回的char*指针
4) 连接两个字符串,组成第三个临时string变量
5) debug return后,销毁所有临时变量
这样下来对程序原有执行是大有影响的,尤其是在程序常用接口中加入TRACE,那将严重影响执行效率。
最开始的实现
我们实现的trace主要在函数调用开始,调用结束,和中间部分写log信息。
上面的trace实现,经过测试,程序加入trace前后,效率降低了20%之多!!!
问题在哪呢?
工程师对C++执行会有不同的理解,但是如下是最基本可知的原则:
1) I/0开销很大
2) 经常调用,而且很简短的函数声明为inline
3) 拷贝实例开销大,多传引用而不是实例
而我们的代码都符合3条原则,问题在于创建了过多我们并未真正使用的实例,下面是Trace的最小用例,程序调用开始和结束时写log记录。
它包含了如下开销:
1)创建string实例name保存“myFunction”
2) 调用Trace的构造函数
3)Trace的构造函数调用string的构造函数,来初始化string成员
(函数调用结束时)
4)析构string实例name
5)调用Trace的析构函数
6)Trace析构函数调用string的析构函数,销毁string成员
实际上,当我们不要用Trace做log,上面这些实例都是完全无用的,这些开销白白浪费掉了。来做如下测试:
我们将函数修改为如下,对比前后执行时间:
执行结果显示,前后执行时间为55ms和3500ms,相差了超过60倍!!!!
The Recovery Plan
修改1,把addOne中创建的string实例name换成Char*,修改如下:
这样,我们去除了name string实例的创建和析构的开销,执行时间由3500ms降到2500ms。
下一步,去除Trace中string成员变量的不必要开销,成员变量用string指针代替,使用指针的好处是调用构造时,不会自动调用成员的构造函数,只是初始化指针值。我们可以辨别Trace状态,再调用构造函数。
通过这一步优化,Trace中string实例的不必要开销也消除了。执行时间降到了185ms。
Key Point
1)不要传实例,多用引用
2)常用的简单函数声明为inline
3)I/O开销大
4)尽量减小可能不被使用成员的调用构造、析构函数
http://blog.chinaunix.net/uid-25872711-id-3013832.html
Efficient C++ 第一章
Charpter 1 The tracing war story
很多时候,为了方便查找bug,会使用trace。比如用如下方式:
#ifdef TRACE Trace t("myFuction"); // Constructor takes a function name argument t.debug("Some information message"); #endif
这样的方式不错,但是问题是:每次TRACE宏的开头都要重新编译代码。想到用如下方式避免这一问题:
void Trace::debug(string &msg) { if (traceIsActive) { // log message here } }
加入一个traceIsActive变量来控制log开关,因为写log开销最大,这样看上去也算可行。下面看,假设有如下调用:
t.debug("x = " + itoa(x)); // itoa() converts an int to ascii
即使,traceIsActive为false,上面的调用还是会产生如下开销:
1) 创建一个临时string变量保存“x=”
2) 调用itoa()函数
3) 创建一个临时string变量保存itoa(x)返回的char*指针
4) 连接两个字符串,组成第三个临时string变量
5) debug return后,销毁所有临时变量
这样下来对程序原有执行是大有影响的,尤其是在程序常用接口中加入TRACE,那将严重影响执行效率。
最开始的实现
我们实现的trace主要在函数调用开始,调用结束,和中间部分写log信息。
class Trace { public: Trace (const string &name); ~Trace (); void debug (const string &msg); static bool traceIsActive; private: string theFunctionName; }; inline Trace::Trace(const string &name) : theFunctionName(name) { if (TraceIsActive){ cout << "Enter function" << name << endl; } } inline void Trace::debug(const string &msg) { if (TraceIsActive){ cout << msg << endl; } } inline Trace::~Trace() { if (traceIsActive) { cout << "Exit function " << theFunctionName << endl; } } //调用 int myFunction(int x) { string name = "myFunction"; Trace t(name); ... string moreInfo = "more interesting info"; t.debug(moreInfo); ... }; // Trace destructor logs exit event to an output stream
上面的trace实现,经过测试,程序加入trace前后,效率降低了20%之多!!!
问题在哪呢?
工程师对C++执行会有不同的理解,但是如下是最基本可知的原则:
1) I/0开销很大
2) 经常调用,而且很简短的函数声明为inline
3) 拷贝实例开销大,多传引用而不是实例
而我们的代码都符合3条原则,问题在于创建了过多我们并未真正使用的实例,下面是Trace的最小用例,程序调用开始和结束时写log记录。
int myFunction(int x) { string name = "myFunction"; Trace t(name); ... };
它包含了如下开销:
1)创建string实例name保存“myFunction”
2) 调用Trace的构造函数
3)Trace的构造函数调用string的构造函数,来初始化string成员
(函数调用结束时)
4)析构string实例name
5)调用Trace的析构函数
6)Trace析构函数调用string的析构函数,销毁string成员
实际上,当我们不要用Trace做log,上面这些实例都是完全无用的,这些开销白白浪费掉了。来做如下测试:
int addOne(int x) // Version 0 { return x+1; } int main() { Trace::traceIsActive = false;//Turn tracing off //... GetSystemTime(&t1); // Start timing for(i =0; i < j; i++) { y = addOne(i); } GetSystemTime(&t2); // Stop timing // ... }
我们将函数修改为如下,对比前后执行时间:
int addOne(int x) // Version 1. Introducing a Trace object { string name = "addOne"; Trace t(name); return x+1; }
执行结果显示,前后执行时间为55ms和3500ms,相差了超过60倍!!!!
The Recovery Plan
修改1,把addOne中创建的string实例name换成Char*,修改如下:
int addOne(int x) // Version 2. Forget the string object. // Use a char pointer instead. { char *name = "addOne"; Trace t(name); return x+1; } //做上面修改,同时Trace构造函数修改为: inline Trace::Trace(const char *name) : theFunctionName(name)// Version 2 { if (traceIsActive){ cout << "Enter function" << name << endl; } }
这样,我们去除了name string实例的创建和析构的开销,执行时间由3500ms降到2500ms。
下一步,去除Trace中string成员变量的不必要开销,成员变量用string指针代替,使用指针的好处是调用构造时,不会自动调用成员的构造函数,只是初始化指针值。我们可以辨别Trace状态,再调用构造函数。
class Trace { //Version 3. Use a string pointer public: Trace (const char *name) : theFunctionName(0) { if (traceIsActive) { // Conditional creation cout << "Enter function" << name < endl; theFunctionName = new string(name); } } ... private: string *theFunctionName; }; inline Trace::~Trace() { if (traceIsActive) { cout << "Exit function " << *theFunctionName << endl; delete theFunctionName; } }
通过这一步优化,Trace中string实例的不必要开销也消除了。执行时间降到了185ms。
Key Point
1)不要传实例,多用引用
2)常用的简单函数声明为inline
3)I/O开销大
4)尽量减小可能不被使用成员的调用构造、析构函数
- Efficient.C__.Performance.Programming.Techniques.zip (1.4 MB)
- 下载次数: 0
发表评论
-
FreeRTOS
2022-03-05 16:31 248Ref https://blog.csdn.net/weix ... -
串口通讯相关
2018-11-02 13:44 411https://bbs.csdn.net/wap/topics ... -
[转]C++验证IP是否可以PING通
2018-10-30 17:54 1325https://www.cnblogs.com/guoyz13 ... -
C++/MFC 換皮膚
2018-10-20 11:05 477https://blog.csdn.net/u01123991 ... -
WinCE 截屏 - C++ 代碼
2018-08-31 09:45 574// this function create a bmp ... -
Android NDK搭建環境
2017-11-27 13:25 580https://www.cnblogs.com/ut2016- ... -
8583协议相关
2017-10-17 13:38 5738583相关资料,整理中... -
Java高级应用之JNI
2017-06-19 09:00 600参考link http://www.cnblogs.com/l ... -
C++实现ping功能
2017-04-18 11:21 2155基础知识 ping的过程是向目的IP发送一个type=8的I ... -
OpenSSL 编译环境搭建
2017-03-27 15:01 9061 安裝VS2008到 c:\Program Files (x ... -
最优非对称加密填充(OAEP)
2017-03-25 14:53 1582OpenSSL命令---rsautl http://blog. ... -
[Platform Builder] 设置SVM OS build Env
2016-11-10 11:39 01 copy one OSDesign Project to ... -
[Windows] System Error Codes(GetLastError )0-----5999
2016-10-26 13:28 1881ERROR_SUCCESS 0 (0x0) T ... -
开源Windows驱动程序框架
2016-09-17 21:35 871转自 http://code.csdn.net/news/28 ... -
c/c++代码中执行cmd命令
2016-09-14 14:50 1908转自 http://blog.csdn.net/slixinx ... -
C#使用C++标准DLL实例(包含callback)
2016-09-11 19:44 1086C++编写标准Win32DLL如下 头文件 /***** ... -
C#调用C++的DLL搜集整理的所有数据类型转换方式
2016-09-09 16:07 969转自 http://www.cnblogs.com/zeroo ... -
WinCE CPU使用率计算 测试工具
2016-09-08 16:14 991转自 http://blog.csdn.net/jan ... -
switch在C++与C#中的一些差异
2016-09-08 15:19 810参考链接 http://blog.csdn.net/weiwe ... -
C++ 鼠标模拟程序
2016-09-04 12:09 1612转自 http://blog.csdn.net/weixinh ...
相关推荐
《Efficient C++》是一本深受C++程序员喜爱的经典书籍,它主要关注如何在C++编程中实现高效、优化的代码。这本书的核心理念是帮助开发者理解C++的底层机制,以便编写出性能更高、资源利用更合理的程序。作者通过一...
《Efficient C++中文版》作为一本专注于高效使用C++的书籍,其内容覆盖了C++编程中的许多高级概念和最佳实践。以下是对该书一些核心知识点的总结和解释: 1. 预处理器指令#define 预处理器指令#define用于定义宏。...
Efficient C++ 英文 CHM 非扫描版 Dov Bulka David Mayhew
《Effective C++: 提高C++性能的编程技术》是一本经典的C++性能优化指南,由Scott Meyers撰写。这本书深入探讨了如何通过编写高效、简洁的代码来最大化C++程序的性能。以下是对该书内容的一些关键知识点的概述: 1....
《Efficient C++: Performance Programming Techniques》是一本深入探讨如何在C++编程中实现高效性能的书籍。由IBM的资深软件专家Scott Meyers和Barbara E. Moo共同撰写,这本书结合了他们在处理高要求性能系统时...
《Efficient C++ Performance Programming Techniques》是一本深入探讨C++性能优化的经典著作,作者是Scott Meyers。这本书针对C++程序员提供了许多实用的技巧和策略,帮助他们在编写代码时能够兼顾效率与性能。以下...
《Efficient C++ Performance Programming Techniques》是一本专为C++程序员设计的性能优化指南,它深入探讨了如何在C++编程中实现高效的代码执行。这本书不仅涵盖了基础的编程技巧,还涉及了许多高级主题,旨在帮助...
《Effective C++:性能编程技术》是一本深受程序员喜爱的经典书籍,主要针对C++语言的高效性能优化提供了诸多实用技巧和建议。这本书深入探讨了如何通过优化代码来提高C++程序的运行效率,同时保持代码的清晰性和可...
相当经典的一本C++书!学习C++必备。
"Modern and efficient C++ Thread Pool Library"很可能是一个第三方库,旨在提供比标准库更高级、性能更好的线程池实现。这个库可能包含以下关键知识点: 1. **线程池概念**:线程池是一组预先创建的线程,等待...
- **第一版到第二版**:主要增加了对C++98新特性的讨论,如模板和异常处理。 - **第二版到第三版**:针对C++11及后续标准进行了更新,涵盖了新的语言特性,如lambda表达式、右值引用和类型推断等。 通过阅读这三...
Real-Time C++ Efficient Object-Oriented and Template Microcontroller Programming(3rd) 英文无水印原版pdf 第3版 pdf所有页面使用FoxitReader、PDF-XChangeViewer、SumatraPDF和Firefox测试都可以打开 本...
《Effective C++ 中文版第三版》是一本深入探讨C++编程实践的书籍,由Scott Meyers撰写,旨在帮助读者提升C++编程的效率和专业性。这本书的高清PDF版本提供了一个清晰易读的阅读体验,是C++程序员进阶学习的理想资料...
《Efficient C++ Performance Programming Techniques》是一本针对C++程序员的性能优化指南,由Scott Meyers撰写,是计算机科学的经典著作之一。这本书深入探讨了如何通过优化C++代码来提高程序运行效率,对于想要...
综上所述,《实时C++:高效面向对象与模板微控制器编程》是一本深入探讨如何使用C++语言进行实时系统开发的专业书籍。它不仅提供了理论上的指导,还结合了大量的实践案例,旨在帮助开发者掌握高效的实时系统编程技巧...