初始化 C++ vector 和其他容器的大小有什么优点(如果有的话)?有什么理由不只使用默认的无参数构造函数吗?
基本上,两者之间是否存在显着的性能差异
vector<Entry> phone_book;
vector<Entry> phone_book(1000);
最佳答案
有几种方法可以创建 vector与 n元素,当您事先不知道元素的数量时,我什至会展示一些填充 vector 的方法。
但首先
什么不该做
std::vector<Entry> phone_book;
for (std::size_t i = 0; i < n; ++i)
{
phone_book[i] = entry; // <-- !! Undefined Behaviour !!
}
默认构造的 vector ,如上例所示,创建一个空 vector 。访问 vector 范围之外的元素是未定义行为。并且不要期望得到一个很好的异常(exception)。未定义的行为意味着任何事情都可能发生:程序可能会崩溃,或者看起来可以工作,或者可能以一种不稳定的方式工作。请注意使用 reserve不会改变 vector 的实际大小,即你不能访问 vector 大小之外的元素,即使你为它们保留。push_back (次优)std::vector<Entry> phone_book;
for (std::size_t i = 0; i < n; ++i)
{
phone_book.push_back(entry);
}
这有一个缺点,即在您推回元素时会发生重新分配。这意味着内存分配、元素移动(或复制,如果它们不可移动,或对于 pre c++11)和内存释放(带有对象销毁)。对于 n,这很可能会发生不止一次。相当大。值得注意的是,它保证了push_back的“摊销常数”。这意味着它不会在每个 push_back 之后进行重新分配.每次重新分配都会以几何方式增加大小。进一步阅读:std::vector and std::string reallocation strategystd::vector<Entry> phone_book(n);
for (auto& elem : phone_book)
{
elem = entry;
}
这不会导致任何重新分配,而是所有 n元素最初将被默认构造,然后在每次推送时复制。这是一个很大的缺点,对性能的影响很可能是可以衡量的。 (这对于基本类型不太明显)。std::vector<Entry> phone_book(n, entry);
这是最好的使用方法。当您在构造函数中提供所需的所有信息时,它将进行最有效的分配 + 赋值。这有可能导致无分支代码,如果 Entry 带有用于赋值的矢量化指令有一个简单的复制构造函数。reserve + push_back (情景推荐)vector<Entry> phone_book;
phone_book.reserve(m);
while (some_condition)
{
phone_book.push_back(entry);
}
// optional
phone_book.shrink_to_fit();
不会发生重新分配,并且对象只会构造一次,直到超出保留容量。 push_back的更好选择可以 emplace_back .shrink_to_fit .std::fill_n和 std::back_inserter (情景推荐)#include <algorithm>
#include <iterator>
std::vector<Entry> phone_book;
// at a later time
// phone_book could be non-empty at this time
std::fill_n(std::back_inserter(phone_book), n, entry);
如果您需要在创建后向 vector 填充或添加元素,请使用此选项。std::generate_n和 std::back_inserter (对于不同的 entry 对象)Entry entry_generator();
std::vector<Entry> phone_book;
std::generate_n(std::back_inserter(phone_book), n, [] { return entry_generator(); });
如果每个 entry,您都可以使用它是不同的并且从生成器获得std::vector<Entry> phone_book{entry0, entry1, entry2, entry3};
在大多数情况下,当您有一小部分用于填充 vector 的初始值时,这应该是默认的首选构造函数。std::vector::vector (constructor)std::vector::insert std::generate std::generate_n std::fill std::fill_n 等)std::back_inserter
关于c++ - 初始化 C++ vector 的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25108854/
我的目标是转换表单输入,例如“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看起来疯狂不安全。所以,功能正常,
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我正在写一篇关于在Ruby中几乎一切都是对象的博客文章,我试图通过以下示例来展示这一点:classCoolBeansattr_accessor:beansdefinitialize@bean=[]enddefcount_beans@beans.countendend所以从类中我们可以看出它有4个方法(当然,除非我错了):它可以在创建新实例时初始化一个默认的空bean数组它可以计算它有多少个bean它可以读取它有多少个bean(通过attr_accessor)它可以向空数组写入(或添加)更多bean(也通过attr_accessor)但是,当我询问类本身它有哪些实例方法时,我没有看到默认