stl string的release版本相对于debug版本有什么优化?

proad 2013-06-19 03:57:40
先上代码:


std::string s;
for (size_t idx = 0; idx < 1000000; ++idx)
{
s.append(256, '$');
}


同样的代码,Debug和Release两种模式下运行差别不小:
Debug: 578 ms, 326 MB.
Release: 406 ms, 245 MB.

谁知道release版本相对于debug版本,
处理速度和内存方面,有什么优化?谢谢!
...全文
451 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
proad 2013-06-30
  • 打赏
  • 举报
回复
引用 13 楼 bluewanderer 的回复:
你都没注意到release模式capacity比你实际物理占用大么...?Working set是实际分配的物理内存的尺寸,内存申请之后不会直接分配物理空间,所以release模式string只会占用size那么大的地方而不是capacity那么大。debug模式要填充保护数据,所以会占capacity那么大。 你压根就不知道理论是什么还是别提理论上怎么样了。
正解!感谢! 从new、malloc、HeapAlloc的过程剖析,更深入、更精确的总结在这里: http://blog.csdn.net/proad/article/details/9105907 如有不当,欢迎指正。
bluewanderer 2013-06-26
  • 打赏
  • 举报
回复
引用 11 楼 proad 的回复:
不好意思地说,你这次又跑题了,呵呵 我问的是string的debug与release区别,而不是string与HeapAlloc的区别, 不论debug还是release,string的预先分配都是一样,s.capacity()也一样。 理论上说,debug/release用的内存应该几乎一样,因为只是差一个heap头尾可以忽略不计, 我统计内存占用用的是GetProcessMemoryInfo(),可能是这个函数哪里有误差导致的内存容量不一样。
你都没注意到release模式capacity比你实际物理占用大么...?Working set是实际分配的物理内存的尺寸,内存申请之后不会直接分配物理空间,所以release模式string只会占用size那么大的地方而不是capacity那么大。debug模式要填充保护数据,所以会占capacity那么大。 你压根就不知道理论是什么还是别提理论上怎么样了。
橡木疙瘩 2013-06-26
  • 打赏
  • 举报
回复
不只是你的string在占用内存,否则内存哪来的245 MB,运行库也要占用内存,Debug版的运行库比Release版的运行库占用内存大也很正常。
proad 2013-06-26
  • 打赏
  • 举报
回复
引用 10 楼 bluewanderer 的回复:
考虑问题可不能狗熊掰棒子... string向后添加的速度之所以比你上次用HeapAlloc的速度快,就是string申请的内存总比实际需要的多。 你输出一下s的capacity就知道Debug模式的326M是哪儿来的了。而245M是实际写入过的内存的大小。
不好意思地说,你这次又跑题了,呵呵 我问的是string的debug与release区别,而不是string与HeapAlloc的区别, 不论debug还是release,string的预先分配都是一样,s.capacity()也一样。 理论上说,debug/release用的内存应该几乎一样,因为只是差一个heap头尾可以忽略不计, 我统计内存占用用的是GetProcessMemoryInfo(),可能是这个函数哪里有误差导致的内存容量不一样。
bluewanderer 2013-06-22
  • 打赏
  • 举报
回复
引用 5 楼 proad 的回复:
[quote=引用 2 楼 bluewanderer 的回复:] 如果你注意到你上个帖子我和另外一个人跑题的内容的话,你能发现一个件事就是:Release模式申请内存在真正使用之前是不一定会占用物理内存的。Debug模式因为要填充保护数据所以申请多少就要占用多少物理内存。
这个因素在此处没关系吧,因为“在真正使用之前”这个假设不成立,此处分配的内存总是马上使用了。 请问:Release模式申请内存在真正使用之前是不一定会占用物理内存的?能否举个例子,学习一下。[/quote] 考虑问题可不能狗熊掰棒子... string向后添加的速度之所以比你上次用HeapAlloc的速度快,就是string申请的内存总比实际需要的多。 你输出一下s的capacity就知道Debug模式的326M是哪儿来的了。而245M是实际写入过的内存的大小。
橡木疙瘩 2013-06-22
  • 打赏
  • 举报
回复
inline关键字基本上已经失效了,debug版本会忽略这一说明,所有函数都不inline。release版本会进行判断,太复杂的inline函数也不会inline,而简单的非inline的static全局函数、类模板函数、匿名空间中的函数、在函数定义的同一cpp文件中调用的函数(它们的共同特点就是在编译调用代码时能找到函数的定义代码)都会被编译为inline。
  • 打赏
  • 举报
回复
引用 7 楼 proad 的回复:
[quote=引用 4 楼 akirya 的回复:] debug版在函数调用前后插入栈检查的代码 debug一般不会内联
是看到有人说stl的debug模式inline方式用的少些, 但没看到具体代码和例子,能随便举个例子? 按我的理解,stl所有函数的实现都是放在头文件的class声明内,不管debug/release函数效果都是inline.[/quote] 反编译试试看呗
proad 2013-06-22
  • 打赏
  • 举报
回复
引用 4 楼 akirya 的回复:
debug版在函数调用前后插入栈检查的代码 debug一般不会内联
是看到有人说stl的debug模式inline方式用的少些, 但没看到具体代码和例子,能随便举个例子? 按我的理解,stl所有函数的实现都是放在头文件的class声明内,不管debug/release函数效果都是inline.
proad 2013-06-22
  • 打赏
  • 举报
回复
TO u010936098: 确实如此,简而言之, std::string分配内存用的是new/malloc/HeapAlloc,释放内存用的是delete/free/HeapFree DEBUG下:分配的内存块前额外有个_CrtMemBlockHeader结构,记录该内存块的信息,内存块尾部有4个字节0xfdfdfdfd,用于在释放时检查是否被越界写操作过。因此,分配的内存额外多了sizeof(_CrtMemBlockHeader)+4个字节,而且每次分配和释放时都要对这些额外空间写操作,消耗的内存和时间都要多; 而RELEASE下,分配的内存没有额外的,因此又快又节省内存。
proad 2013-06-22
  • 打赏
  • 举报
回复
引用 2 楼 bluewanderer 的回复:
如果你注意到你上个帖子我和另外一个人跑题的内容的话,你能发现一个件事就是:Release模式申请内存在真正使用之前是不一定会占用物理内存的。Debug模式因为要填充保护数据所以申请多少就要占用多少物理内存。
这个因素在此处没关系吧,因为“在真正使用之前”这个假设不成立,此处分配的内存总是马上使用了。 请问:Release模式申请内存在真正使用之前是不一定会占用物理内存的?能否举个例子,学习一下。
  • 打赏
  • 举报
回复
debug版在函数调用前后插入栈检查的代码 debug一般不会内联
橡木疙瘩 2013-06-21
  • 打赏
  • 举报
回复
Debug版本分配的内存时通常会多分配一些(一般是一个整数),并在里面写入一个固定值,然后在内存释放时检查这个值是否改变,以便于更容易发现越界写错误。 Debug版本分配内存时会用某个数值去填充内存块,以便于更容易发现未初始化的错误。 Debug版本释放内存时会用某个数值去填充内存块,以便于更容易发现释放后访问的错误。 Debug版本在operator[]操作、迭代器访问时都会检查是否越界,release版本不做检查。此外at成员函数在release版本也会进行越界检查,并可能抛出out_of_range异常,因此它比operator[]慢。 Debug版本调用的是调试库,里面到处都是验证前置条件和后置条件的assert,而release版本没有这些验证。 总之,Debug版本的一切设置都把“更容易发现错误”作为第一目标,效率完全不在它的考虑范围之内。如果你发现某个Debug版的二分查找比顺序查找还慢,千万不要吃惊,这是很正常的,因为它的实现代码中很可能被加上了一段O(n)的代码来检查传进的序列是否有序,而这段代码不会出现在Release版本中。
bluewanderer 2013-06-21
  • 打赏
  • 举报
回复
如果你注意到你上个帖子我和另外一个人跑题的内容的话,你能发现一个件事就是:Release模式申请内存在真正使用之前是不一定会占用物理内存的。Debug模式因为要填充保护数据所以申请多少就要占用多少物理内存。
proad 2013-06-21
  • 打赏
  • 举报
回复
这个。。。没人知道?
Usage: configure [-h] [-prefix ] [-prefix-install] [-bindir ] [-libdir ] [-docdir ] [-headerdir ] [-plugindir ] [-importdir ] [-datadir ] [-translationdir ] [-sysconfdir ] [-examplesdir ] [-demosdir ] [-buildkey ] [-release] [-debug] [-debug-and-release] [-developer-build] [-shared] [-static] [-no-fast] [-fast] [-no-largefile] [-largefile] [-no-exceptions] [-exceptions] [-no-accessibility] [-accessibility] [-no-stl] [-stl] [-no-sql-] [-sql-] [-plugin-sql-] [-system-sqlite] [-no-qt3support] [-qt3support] [-platform] [-D <string>] [-I <string>] [-L <string>] [-help] [-qt-zlib] [-system-zlib] [-no-gif] [-no-libtiff] [-qt-libtiff] [-system-libtiff] [-no-libpng] [-qt-libpng] [-system-libpng] [-no-libmng] [-qt-libmng] [-system-libmng] [-no-libjpeg] [-qt-libjpeg] [-system-libjpeg] [-make ] [-nomake ] [-R <string>] [-l <string>] [-no-rpath] [-rpath] [-continue] [-verbose] [-v] [-silent] [-no-nis] [-nis] [-no-cups] [-cups] [-no-iconv] [-iconv] [-no-pch] [-pch] [-no-dbus] [-dbus] [-dbus-linked] [-no-gui] [-no-separate-debug-info] [-no-mmx] [-no-3dnow] [-no-sse] [-no-sse2] [-no-sse3] [-no-ssse3] [-no-sse4.1] [-no-sse4.2] [-no-avx] [-no-neon] [-qtnamespace ] [-qtlibinfix ] [-separate-debug-info] [-armfpa] [-no-optimized-qmake] [-optimized-qmake] [-no-xmlpatterns] [-xmlpatterns] [-no-multimedia] [-multimedia] [-no-phonon] [-phonon] [-no-phonon-backend] [-phonon-backend] [-no-media-backend] [-media-backend] [-no-audio-backend] [-audio-backend] [-no-openssl] [-openssl] [-openssl-linked] [-no-gtkstyle] [-gtkstyle] [-no-svg] [-svg] [-no-webkit] [-webkit] [-webkit-debug] [-no-javascript-jit] [-javascript-jit] [-no-script] [-script] [-no-scripttools] [-scripttools] [-no-declarative] [-declarative] [-no-declarative-debug] [-declarative-debug] [additional platform specific options (see below)]

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧