if (!infile)
{
cerr << "文件打开失败" << endl;
return -1;
}
string str;
while (getline(infile, str, '\n'))
{
str_vect.push_back(str);
}
//====================
但这样明显有一个多余的内存拷贝操作,就是 filebuffer ->str->vector
那么我们是否可以给vector添加一个loadFile()方法,来省去push_back()操作呢?
ps.
当然,我知道这个带来的性能提升与磁盘的速度比起来可能会微不足道。
但,很难想象如果一个程序中大量的内存拷贝操作,这个程序的性能会很好。
找一个profiler,做一下profiling再决定是不是要改进这个吧,即使要改进,也先设置一下reserve的元素数量,或者重新设计一下程序结构,再决定是否要打破现有机制。
介绍一个profiler: http://wwhttp://society.solidot.org/article.pl?sid=09/07/03/0650209w.glowcode.com/ 这个东西是收费的,但是可以试用
Profiling in software
In software engineering, performance analysis, more commonly known today as profiling, is the investigation of a program’s behavior using information gathered as the program executes (i.e. it is a form of dynamic program analysis, as opposed to static code analysis). The usual goal of performance analysis is to determine which sections of a program to optimize — usually either to increase its speed or decrease its memory requirement (or sometimes both).
continue to read online:
http://docs.google.com/View?id=dcrhkvwg_124f7b38qfm
On Jul 30, 7:02 pm, 周龙亭 <njdragon...@gmail.com> wrote:
> 使用 vector<string *> 可以吗
>
> 2009/7/30 up duan <fixo...@gmail.com>
>
> > vector是非侵入式的容器,这就意味着它最初设计的时候就是以值语义和copy为其行为基础的。
> > 如果希望免除copy,可以看看boost下的侵入式的list。
>
> > 另外,vector之类的内存连续的容器,做成copyless的应该很难吧。
>
> > 2009/7/30 sagasw <sag...@gmail.com>
>
> >> 使用这个PerfTimer很简单(代码已经包含在文章里)。
> >> CPerfTimer timer(TRUE);
> >> ....
> >> timer.stop();
> >> miliseconds = timer.EstimateMS();
>
> >> 2009/7/30 sagasw <sag...@gmail.com>
>
> >> Profiling C++ performance in windows <http://sunxiunan.com/?p=1216>
>
> >>> Profiling in software
> >>> http://en.wikipedia.org/wiki/Software_profiling
>
> >>> In software engineering<http://en.wikipedia.org/wiki/Software_engineering>,
> >>> *performance analysis*, more commonly known today as *profiling*, is the
> >>> investigation of a program's behavior using information gathered as the
> >>> program executes (i.e. it is a form of dynamic program analysis<http://en.wikipedia.org/wiki/Dynamic_program_analysis>,
> >>> as opposed to static code analysis<http://en.wikipedia.org/wiki/Static_code_analysis>).
> >>> The usual goal of performance analysis is to determine which sections of a
> >>> program to optimize<http://en.wikipedia.org/wiki/Optimization_%28computer_science%29>-- usually either to increase its speed or decrease its memory requirement
> >>> (or sometimes both).
>
> >>> continue to read online:
>
> >>> *http://docs.google.com/View?id=dcrhkvwg_124f7b38qfm*
>
> >>> 2009/7/30 Kenny Yuan <yuankain...@gmail.com>
>
> >>>> 找一个profiler,做一下profiling再决定是不是要改进这个吧,即使要改进,也先设置一下reserve的元素数量,或者重新设计一下程序结构,再决定是否要打破现有机制。
>
> >>>> 介绍一个profiler:http://www.glowcode.com/这个东西是收费的,但是可以试用
>
> >>>> 另外,磁盘操作有时候不像想像中的那么慢,像这种逐行读入vector的东西,有时候磁盘并不是瓶颈----一切都要经过profiling之后才清晰
>
> >>>> 2009/7/30 xLight <xblueli...@gmail.com>
参考:http://www.ddj.com/cpp/184403485
> >>>>>> 找一个profiler,做一下profiling再决定是不是要改进这个吧,即使要改进,也先设置一下reserve的元素数量,或者重新设计一下程序结构,-再决定是否要打破现有机制。
> >>>>>> URL2:http://blog.csdn.net/yuankaining/- 隐藏被引用文字 -
>
> - 显示引用的文字 -
虽然STL容器允许指定allocator,但是实现一个安全健壮高效的allocator难度不小。一般人要写也就写一个trivial的包装
new/delete或malloc/free的allocator罢了。
我甚至觉得这是一个多余的设计,就像iostream的locale一样。真要追求极高效率,恐怕不是替换allocator这么简单,估计连STL都
会弃之不用。
楼主,你能不能先告诉我们,现在这个程序读入数据的运行时间是多少?如果把push_back注释掉,光读一遍文件的运行时间又是多少?这样大家好有的
放矢。
Ian Yang 写道:
> gcc可以用gprof
>
>
> 开源软件还有valgrind可以做profiling
>
>
> -------
> Sincerely, Ian Yang
>
>
> Sent from Shanghai, 31, China
>
> 2009/7/30 Kenny Yuan <yuank...@gmail.com
> <mailto:yuank...@gmail.com>>
>
> 找一个profiler,做一下profiling再决定是不是要改进这个吧,即使要改
> 进,也先设置一下reserve的元素数量,或者重新设计一下程序结构,再决
> 定是否要打破现有机制。
>
> 介绍一个profiler:
> http://wwhttp://society.solidot.org/article.pl?sid=09/07/03/0650209w.glowcode.com/
> <http://www.glowcode.com/> 这个东西是收费的,但是可以试用
>
> 另外,磁盘操作有时候不像想像中的那么慢,像这种逐行读入vector的东
> 西,有时候磁盘并不是瓶颈——一切都要经过profiling之后才清晰
>
> 2009/7/30 xLight <xblue...@gmail.com <mailto:xblue...@gmail.com>>
xLight 写道:
根据你的vector<string>是如何被操作的,有很多种优化方案,vector<string>,这种类型实在是垃圾,vector<const char*>都比这强;
> > > >>>>>> 找一个profiler,做一下profiling再决定是不是要改进这个吧,即使要改进,也先设置一下reserve的元素数量,或者重新设计一下程序结构,--再决定是否要打破现有机制。
> > > - 显示引用的文字 -- 隐藏被引用文字 -
>
> - 显示引用的文字 -
这正好是实现绑架标准的一个例子。名义上给用户更多选择,甚至允许用户定制,实际上大家都用默认配置。allocator不过是个摆设罢了。
> > > > > >>>>>> 找一个profiler,做一下profiling再决定是不是要改进这个吧,即使要改进,也先设置一下reserve的元素数量,或者重新设计一下程序结构,---再决定是否要打破现有机制。
对于vector,还有其他一些可以定制的点:
1. 容量增长的策略,是1.5倍还是2倍?这个在库的代码里是写死的,两种我都见过,但用户不能自己选择。
2. 容量增长时,搬移对象是用拷贝构造还是默认构造+swap。这个也是写死的,用拷贝构造。对于vector<string>,对于非copy-
on-write的string实现,等于要复制整个字符串。如果vector<string>采用默认构造+swap来实现,那么在resize时,
每个string只要交换几个指针,可能快得多。这个也没法让用户自己选。
这些东西有没有必要也让用户自己选择呢?既然allocator可以,为什么这些就不行?
vector接受allocator为模板参数,而非构造函数的参数,这个很诡异。相反,shared_ptr就只有一个模板参数T,而他同样可以指定
allocator----在构造时传入。感谢标准委员会没有选择policy based smart pointer,而选用了boost的这个简单好
用的shared_ptr。
现在看来,vector(以及其他标准库容器)与其增加一个Alloc模板参数,不如在构造时传入两个函数指针,一个allocate,一个
deallocate,定制的效果也一样。只不过这么做会让标准委员会的人觉得不够GP,很可能被拍掉。
On Jul 31, 11:03 pm, 李诒雯 <liyiwen...@gmail.com> wrote:
> 感觉确实会有用的,至少给了一条可能的途径。比完全写死要好,反正在有默认模板参数的情况下,分离出allocator也没有给使用上带来麻烦。
>
> 目前接触的一个嵌入式软件(导航类)中,HMI部分的内存是有限制的,并且要实现很多调试方面的功能,系统本身做了一个内存池,大小固定死了(15M?记得不太清楚了),HMI部分的"动态"内存都从这个内存池中取用。当然这个系统是用C写的,同样的情形下,如果用C++(我是说如果,其实我没有这方面实际经验,但目前正在用C++
> 模仿,重写这套系统的基本框架
> ),那么通过设计自己的allocator就有可能重用STL,否则,肯定得重写一套(估计要达到或超过STL的质量也是不太容易)。
>
> 这也许是一个不太恰当的例子,但应该可以找出类似的"情景"。用的人多了,就会有各种需求。能方便地提供更多的"可能"可以增加库的适应性。
>
> 2009/7/31 许海斌 <thisis...@gmail.com>
C/C++里的内存分配和释放是个重要的事情,我同意,在写library的时候,除了默认使用malloc/free,还应该允许用户指定使用内存分
配的函数。用现在的话说,如果library依赖于内存分配与释放,就应该允许用户注入这种依赖。我看到有些C library是支持这个的,可以在初
始化时传入两个函数指针,指向内存分配和释放的函数。
问题是,allocator是模板参数,而不是构造函数的参数。这意味着
1. 由于不能从构造函数传入allocator,那么allocator必须是全局唯一的。无论SGI 的内存池(称为PoolAlloc),还是简
单的new wrapper(称为NewAlloc)都只从一个地方(region)搞到内存,这大大限制了其使用。
2. allocator是vector类型的一部分,vector<string, PoolAlloc> 和 vector<string,
NewAlloc> 是两个类型,不可相互替换。这不仅暴露了实现,还暴露到了类型上,恐怕没有比这更糟糕的了。
下面举例说明,
对于1,假设我有一个任务(假设是parse),需要分配很多小块内存,总容量不超过20M。为了防止内存泄露及避免内存碎片,我希望在任务开始时,先
从系统拿到20M内存,供这个任务使用(parse里分配内存只需要改一个指针,释放内存是空操作),等任务完成后,我一次性释放这20M内存,这样既
高效又安全。然而C++的allocator并不能帮我实现这一点,因为它是全局的。我不能替换全局的allocator,因为那会影响其他线程。也不
能在运行时指定某个vector<string>用哪种allocator,因为类型是编译时确定的。
对于2,如果我想写一个普通的以vector<string>为参数的函数,这不难
void process(vector<string>& records);
由于vector<string, PoolAlloc>和vector<string, NewAlloc>类型不同,process只能接受一种。
但这完全没道理,我不过想访问一个vector<string>,根本不关心它的内存是怎么分配的,却被什么鬼东西allocator挡在了门外。
我要么提供重载:
void process(vector<string, NewAlloc>& records);
void process(vector<string, PoolAlloc>& records);
要么改写成模板:
template<typename Alloc>
void process(const vector<string, Alloc>& records); //(同理可知,如果在一个程序里使用多
种allocator,那么所有涉及标准库容器的函数都必须改写为函数模板)
无论哪种"解决办法"都会导致代码膨胀,而且给库的使用者带来完全不必要的负担。
根据以上的分析,基本上不可能在一个程序里混用多种allocator,既然一个程序只能有一种allocator,那为什么还要放到每个容器的模板参
数里呢?
总而言之,allocator并不能达到精确控制(定制)内存分配释放的目的,虽然它名以上是为此而生的。它就是个累赘。
这个时候还用啥标准库嘛,直接上手自己写得了。
> 第2个问题,右值引用是不是更好的方式?
Are you serious?
> 能提供更多的"可能性"当然就更好
包括大多数人一辈子也用不到的"可能性"?奥卡姆剃刀。
On Aug 1, 10:25 am, 李诒雯 <liyiwen...@gmail.com> wrote:
> >>所以C++的标准库吵来吵去也加不了多少新东西,因为众口难调嘛。
>
> 确实如此~~要满足所有人的愿望几乎是不可能的,所以进行适当的取舍是标准委员会应该有的智慧,虽然总是会有人对结果抱怨(毕竟无法满足所有人嘛),但基本上标准委员会成员应该算得上是最有资格做这种取舍的人了吧。
>
> >>vector接受allocator为模板参数,而非构造函数的参数,这个很诡异。相反,shared_ptr就只有一个模板参数T,而他同样可以指定allocator----在构造时传入。感谢标准委员会没有选择policy
>
> based smart pointer,而选用了boost的这个简单好用的shared_ptr。
> 无论作为模板参数还是作为构造函数的参数,可以说明分离出allocator还是必要的,对吧?至于说作为模板参数很诡异,我不知道怎么理解。我觉得两者都差不多,非要让我来说区别,我又会想到"效率"(甚至栈长度......呵呵)上去。总之分离出了alloctor确实增加了适应性嘛,否则当需要对特殊资源进行管理的时候,是不是又得写一套特殊的智能指针。
> 另外就是"智能指针"之争,也有著名的boost vs. loki一文可以看看,起码说明,还有不少执有不同看法的人在。
> 对于我来说,我就觉得只要不增加使用上的麻烦和性能上的折损,能提供更多的"可能性"当然就更好。学习曲线稍微陡峭一点也没关系,反正已经没法把C++当"傻瓜相机"来用了。
>
> >>1. 容量增长的策略,是1.5倍还是2倍?这个在库的代码里是写死的,两种我都见过,但用户不能自己选择。
>
> 2.
> 容量增长时,搬移对象是用拷贝构造还是默认构造+swap。这个也是写死的,用拷贝构>>造。对于vector<string>,对于非copy-on-write的string实现,等于要复制整个字符串。如果vector<string>采用默认构造+swap来实现,那么在resize时,每个string只要交换几个指针,可能快得多。这个也没法让用户自己选。
> 增长策略,我不好说什么,虽然我想不出有什么场景希望自主选择增长1.5还是2倍,但不能说这种选择就是没用的。第2个问题,右值引用是不是更好的方式?
>
> 还是那句话: 对于我来说,我就觉得只要不增加使用上的麻烦和性能上的折损,能提供更多的"可能性"当然就更好。[?]
>
> PS:
> 希望我们没严重跑题,hohoho
>
> 330.gif
> < 1KViewDownload
这种级别的差距,我仅可以勉强认同"他不是真正的瓶颈"
如果在一个web应用上,要求2秒就给用户返回结果,这个30%实在是太有价值了
On 7月31日, 上午8时48分, sagasw <sag...@gmail.com> wrote:
> 忘了加上对比数据了,
> 对于54M那个log文件(前面的两个文件一个是21M一个是54M,点号应该写成逗号),去掉pushback以后
> time 3224.1400ms
>
> 所以基本上可以不考虑pushback的影响,
>
> 要说到关键了:它不是真正的瓶颈。*
> *
> 2009/7/31 sagasw <sag...@gmail.com>
>
>
>
> > 与其在这里说些跑题的话,不如看看这个问题是不是真的存在。
>
> > 我的测试数据:
>
> > time 1854.4241ms 测试文件 SqlSupport_Cpu32_1.log 21.841KB
>
> > time 4556.0256ms 测试文件 Install.log 54.777KB
>
> > 不知道楼主应用要求什么样的响应速度,个人感觉这个速度相对一般应用已经可以了。
>
> > release版,代码基本上使用楼主的代码片段。
>
> > 2009/7/31 Shuo Chen <giantc...@gmail.com>
> >> 找一个profiler,做一下profiling再决定是不是要改进这个吧,即使要改进,也先设置一下reserve的元素数量,或者重新设计一下程序结构,-再决定是否要打破现有机制。
> > > >> 找一个profiler,做一下profiling再决定是不是要改进这个吧,即使要改进,也先设置一下reserve的元素数量,或者重新设计一下程序结构,--再决定是否要打破现有机制。
呵呵,问题在于要读的文件是用户几秒钟之前产生的。
并且不断产生新的,