英语不好,但请理解。
string str;
string str_base = "user name = ";
string str_user_input;
string str_system_message;
...
str = str_base + str_user_input + "n [system message :]" + str_system_message;
cout << str << endl;
我正在使用这样的现有代码,有没有一种方法可以优化字符串?
我认为这段代码做了很多无用的操作。有没有优化的方法?
我认为这段代码做了很多无用的操作。有没有优化的方法?
不要猜测,但要通过分析来衡量
也许(至少在Linux系统上)使用gprof(1)或perf(1、time(1)等实用程序,或者使用clock_gettime(2)等与时间(7)相关的函数。你会在Windows、MacOSX和Android上找到类似的东西。大多数计算机都有一些类似于HPET的硬件。另请参阅OSDEV了解更多信息。
如果使用最新的GCC编译器,请确保启用优化。因此,在使用gprof(1)之前,编译并至少使用g++ -Wall -pg -O2 -flto
链接。还学习使用GDB调试器(或其他调试器)来观察程序的行为(其操作语义)。
你可能会对最近的GCC 10编译器(在2020年夏天)所能进行的优化感到惊讶,因为即使没有inline
的要求,它也会进行内联扩展。如果您碰巧理解汇编代码,请尝试使用命令行g++ -O3 -fverbose-asm -S foo.c
在foo.cc
中编译C++代码,然后查看生成的foo.s
文件。
当然,读一本好的C++编程书,看看这个C++参考网站(以及n3337,一个C++标准)。同时阅读C++编译器(和链接器)的文档。
我认为这段代码做了很多无用的操作。有没有优化的方法?
将此类微优化留给C++编译器
首先确保您的代码是正确的,然后花精力进行分析和优化。
仔细想想,大多数计算机都会花时间做很多无用的操作。阅读已故J.Pitrat的博客和他的《人造人》一书。
作为一名软件开发人员,你的职责是平衡你的开发工作和计算机时间。今天,计算机在大多数时候都比软件开发人员便宜。
如果原始性能非常重要,请花时间编写汇编代码。如果使用Linux,请阅读Linux Assembly HowTo。准备好比C++低10倍的生产力。。。。
如果性能很重要,还可以考虑进行一些元编程和运行时代码生成(例如使用asmjit或libgccjit,或者像SBCL一样)。阅读更多关于部分评估和自动程序生成的信息,还可以阅读Dragon Book和一些算法简介
另一个答案是:
优化问题乍一看是微不足道的
当然不是小事。注意Rice定理
我认为这段代码做了很多无用的操作。有没有优化的方法?
可能。考虑优化的机器学习方法,比如MILEPOST GCC或Ctuning项目。查看(至少可以获得灵感)许多开源项目(包括CHARIOT、GCC、Clang、RefPerSys、Frama-C、Qt、ANTLR、SWIG),生成或分析C++代码。
重要的问题是经济的:将代码优化1%是否值得花费时间(例如,花费个月的精力,也许是编写GCC插件)?在某些情况下,这种努力是值得的,但在大多数情况下却不值得。
您的问题是+=,但您没有在任何地方使用+=。您只使用+。
"可能是连接字符串的最有效方法。还有其他方法,但+不太可能更糟。
正如John Bollinger所说,如果你只需要输出连接的结果,那么直接输出片段:
cout << str_base << str_user_input << "n [system message :]" << str_system_message << endl;
或者使用C++20(正如Thomas Sablik所说):
std::format("{}{}n [system message :]{}", str_base, str_user_input, str_system_message); otherwise: fmt::format("{}{}n [system message :]{}", str_base, str_user_input, str_system_message);
我建议尝试优化代码的其他部分(如果需要的话),因为你不太可能比语言/编译器做得更好。忘记优化+。
从另一个角度来看,请参阅这个问题的答案:
C++中高效的字符串串接
简单地说,有几种方法可以优化这一点:
首先,通过使用+=而不是多个+操作,可以避免创建一些临时对象。
也就是说,更喜欢做:
s += s1;
s += s2;
s += s3;
而不是:
s = s1 + s2 + s3;
其次,调用(上面的+=示例)之前可以将字符串的大小相加,并在s中保留内存。
话虽如此(我确实提到这是一个"简单化"的答案),这里还有一些其他考虑因素:
语言设计者和编译器开发人员已经花了很多时间来优化字符串操作,并且你不太可能通过处理字符串和用户输入的函数中的微优化来显著优化你的代码(除非字符串过大,除非这是关键路径上的代码,除非你在一个非常受限的系统中工作)。
你可能被否决了,因为看起来你正专注于解决错误的问题。
优化问题一开始看起来微不足道,但在您设置了性能目标和衡量当前性能的方法之前,您很可能会在错误的地方寻找优化(看起来就像您现在正在做的那样)。