看一段这样的代码(添加注释):
std::string some_var;
std::string some_func(); // both are defined, but definition is irrelevant
...
return "some text " + some_var + "c" + some_func(); // intentionally "c" not 'c'
我想知道,在哪些情况下 std::string 的 operator + 必须进行复制(在使用复制构造/赋值的意义上,而不是被复制的内部缓冲区,例如如果 SSO 适用),以及实际复制的内容。快速浏览 cppreference只是部分有用,因为它列出了 12(!) 种不同的情况。在某种程度上,我要求确认我对该页面的理解:
char/const char* 参数构造的,然后导致情况 1)char/const char* 参数,然后导致情况 6) 或 7)insert/append 改变,如果 char/const char* 参数已提供,由于 insert/append 上的重载,不需要临时文件。在所有情况下,都会返回一个 r 值以促进进一步链接。不制作任何拷贝(除了要在插入位置附加/插入的参数的拷贝)。可能需要移动字符串的内容。因此,像上面示例这样的链应该导致:2) -> 6) -> 11) -> 8),没有创建任何 lhs 的拷贝,而只是修改了 r 值的缓冲区从第一个操作(创建临时字符串)开始。
因此,这似乎与 operator += 一样有效,一旦 operator + 至少使用了右值参数。这是否正确,在 C++11 及之后的 operator + 上使用 operator += 是否有任何意义,除非两个参数都是 l-值字符串?
编译器还可以做哪些优化?
编辑:阐明问题的意图。初始部分仅与语言的细节有关(不支持实现);最后一个问题是关于额外的优化。
最佳答案
字符串是一个相当不透明的对象:它拥有一个内部字符缓冲区并按照它想要的方式管理它。将单个字符添加到字符串可能会以分配新缓冲区、初始部分的拷贝和添加部分的拷贝结束。一切都取决于分配的缓冲区是否足够大以接受添加的部分。
引文说:
... No copies are made (except the copy of the arguments to be appended/inserted at the insertion location). The contents of the string may need to be moved.
换句话说,新分配,旧缓冲区的完整复制和释放...
当您谈到效率和优化时,您必须记住编译器不必遵循您编写程序的方式。由于 as-if 规则,它可以优化它想要的方式,前提是尊重可观察的行为。 C++ 标准说:
1.9 Program execution [intro.execution]
...
5 A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input.
注释解释了这一点:
an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program.
所以很可能 a = a + b; 和 a += b; 被编译成完全相同的代码。
当您编写 C++ 程序时,您永远不必担心低级优化:编译器会关心它,而且通常说编译器比您聪明。仅当您确定了真正的瓶颈时才采用这种方式,并注意如果仅针对一种体系结构和一种配置上的一种编译器进行低级优化。
关于C++ 字符串连接优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41857372/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server