有什么方法可以优化c ++字符串+ =运算符?

问题描述

英语不好,但是请理解。

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),或者具有与time(7)相关的功能,例如clock_gettime(2)。您至少会发现for Windows以及MacOSX和Android类似的东西。大多数计算机的硬件类似于HPET。另请参见OSDEV

如果您使用最新的GCC编译器,请确保启用optimizations。因此,在使用with之前,至少编译{em>并链接 gprof(1) g++ -Wall -pg -O2 -flto。还学习使用GDB调试器(或另一个调试器)观察程序(其operational semantics)的行为。

您可能会对最近的GCC 10编译器能够(在2020年夏季)实现的优化感到惊讶,因为即使没有要求inline时,编译器也可以执行inline expansion。如果您碰巧了解汇编代码,请尝试使用命令行foo.ccg++ -O3 -fverbose-asm -S foo.c中编译C ++代码,然后查看生成的foo.s文件。

当然,请阅读优质的C++ programming book并访问this C++ reference网站(和n3337,这是C ++标准)。并阅读您的C ++编译器(和链接器)的文档。

我认为这段代码做了很多无用的操作。有没有优化的方法?

将此类微优化留给C ++编译器。

首先确保您的代码正确,然后花精力进行概要分析和优化。

想到这一点,大多数计算机会花费大量时间进行许多无用的操作。阅读blog of the late J.Pitrat和他的Artificial beings book

作为软件开发人员,您的角色是在开发工作量和计算机时间之间取得平衡。如今,计算机通常比软件开发人员便宜

如果原始性能非常重要,请花时间编写汇编代码。如果使用Linux,请阅读Linux Assembly HowTo。准备比C ++的生产力低10倍。...

如果性能很重要,还考虑进行一些metaprogramming和运行时代码生成(例如,使用asmjitlibgccjit,或者像SBCL一样)。阅读有关partial evaluation and automatic program generation的更多信息,还阅读Dragon Book和一些Introduction to Algorithms

Another answer说:

优化问题乍一看并不重要

肯定不是不重要的。请注意Rice's theorem

我认为这段代码做了很多无用的操作。有没有优化的方法?

可能是。考虑使用machine learning进行优化的方法,例如在MILEPOST GCCCtuning项目中。在许多开源项目(包括CHARIOTGCCClangRefPerSysFrama-CQtANTLRSWIG生成分析 C ++代码。

重要的问题是经济的:将您的代码优化1%是否值得您花费时间(例如,花费几个月的精力,也许编写GCC plugin)?在某些情况下,值得付出努力,而在大多数情况下却不值得。

,

您的问题说+ =,但是您没有在任何地方使用+ =。您仅使用+。

“ +”可能是连接字符串的最有效方法。还有其他方法,但是+不太可能恶化。

如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_system_message);

我建议改而优化代码的其他部分(如果需要),因为它不太可能比语言/编译器做得更好。忘记优化+。

从另一个角度来看,请参考该问题的答案:

Efficient string concatenation in C++

,

简单地说,有多种方法可以对此进行优化:

首先,通过使用+ =而不是多个+操作,您将避免创建某些临时对象。

也就是说,更愿意这样做:

s += s1;
s += s2;
s += s3;

代替:

s = s1 + s2 + s3;

第二,在调用之前(上面的+ =示例),可以先增加字符串的大小并在s中保留内存。

话虽如此(我的确提到过,这是一个“简单化”的答案),这里还有其他一些注意事项:

  • 语言设计人员和编译器开发人员已经花费了大量时间来优化字符串操作,并且您不可能通过微优化函数来显着优化代码,该函数处理字符串和用户输入(除非字符串过大) ,除非这是关键路径上的代码,并且除非您在非常受限的系统中工作)。

  • 您可能被否决了,因为您似乎专注于解决错误的问题。

  • 优化问题乍一看似乎微不足道,但是在您设定性能目标和衡量当前性能的方法之前,您可能会在错误的地方寻找优化(看起来就像您现在正在做的那样) )。