以下两种在a末尾插入新元素的方法在性能上是否有任何区别std::vector:
std::vector<int> vec = { 1 };
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
Run Code Online (Sandbox Code Playgroud)
std::vector<int> vec = { 1 };
int arr[] = { 2,3,4,5 };
vec.insert(std::end(vec), std::begin(arr), std::end(arr));
Run Code Online (Sandbox Code Playgroud)
就我个人而言,我喜欢方法2,因为它很好且简洁,可以一次性插入数组中的所有新元素。但
首先,我不使用所有元素初始化向量的原因是,在我的程序中,我根据条件添加了其余元素。
我只是比较将字符串传递给函数的性能。该基准测试结果很有趣。
这是我的代码:
void add(std::string msg)
{
msg += "world";
}
void addRvalue(std::string&& msg)
{
msg += "world";
}
void addRef(std::string& msg)
{
msg += "world";
}
void StringCreation() {
add(std::string("hello "));
}
void StringCopy() {
std::string msg("hello ");
add(msg);
}
void StringMove() {
std::string msg("hello ");
add(std::move(msg));
}
void StringRvalue() {
std::string msg("hello ");
addRvalue(std::move(msg));
}
void StringReference() {
std::string msg("hello ");
addRef(msg);
}
Run Code Online (Sandbox Code Playgroud)
StringCreation(),StringRvalue()和StringReference()是等效的。我很惊讶StringMove()是性能最低的-比涉及复制的值传递差。
我是否认为调用StringMove()涉及一个移动构造函数,然后在调用add()时涉及一个复制构造函数,对吗?它不仅仅涉及一举动的构造函数吗?我以为搬家的建设很便宜。
我增加了传递给add()的字符串的长度,这确实有所作为。现在,StringMove()仅比StringCreation和StringReference慢1.1倍。StringCopy现在是最糟糕的,这正是我所期望的。
这是新的基准测试结果。
因此,StringMove根本不涉及复制-仅适用于小字符串。
我有一种非常低效的方法来计算N/2大小为N的数组中的项组合.我所做的是先对数组进行排序,然后循环遍历数组的排列,创建具有一半元素的多重集并将其插入到一套.最后我得到了集合的计数.
long GetCombinations(std::vector<double> nums) {
long combinations = 0;
std::sort(nums.begin(), nums.end());
std::set<std::multiset<double>> super_set;
do {
std::multiset<double> multi_set;
for (unsigned int i = 0; i < nums.size() / 2; ++i)
multi_set.insert(nums[i]);
auto el = (super_set.insert(multi_set));
if (el.second)
++combinations;
} while (std::next_permutation(nums.begin(), nums.end()));
return combinations;
}
Run Code Online (Sandbox Code Playgroud)
代码有效,但效率很低.对于给定的数组[0.5, 0.5, 1, 1],有3种大小为2的组合:
0.5,0.5
1,1
1,0.5
是否有不同的算法或方法可以提高此代码的速度?
我正在做一些涉及std:vector. 我从一个相对较小的 100 个整数向量开始,并调用各种方法用 1,000,000 个整数填充它。我的大多数功能涉及清除元素并再次添加元素或创建新向量并将其移动或与原始向量交换。我还有一个函数可以调整向量大小并覆盖元素。
您可以在下面的代码中看到这些函数。有趣的是,调整向量大小并覆盖元素是迄今为止最快的。我认为在推送元素之前保留内存会提高性能。
我知道这std::vector::resize()将调整向量的大小以包含新的计数。根据cppreference:
如果当前大小小于 count,则会附加其他元素并使用值的副本进行初始化。
resize()应该比其他函数少构造 100 个整数。所以我对速度的差异感到惊讶。我认为resize()会分配并初始化新元素,而保留只会分配内存。
#include <algorithm>
#include <chrono>
#include <iostream>
constexpr int InitialSize = 100;
constexpr int NewSize = 1000000;
void overwrite(std::vector<int>& v)
{
v.resize(NewSize);
for (int i = 0; i < NewSize; ++i)
{
v[i] = i;
}
}
void clear(std::vector<int>& v)
{
v.clear();
v.reserve(NewSize);
for (int i = 0; i < NewSize; ++i)
{
v.push_back(i);
}
}
void swap(std::vector<int> &v) …Run Code Online (Sandbox Code Playgroud) 有没有可能的方法在类中使用线程,如下所示:
Class Logger // singleton class
{
//.... here is implemented thread logic
{
void main()
{
Logger& log = Logger::getInstance();
log.writeMessage(); // this should execute in another thread
// also, all the other func from Logger class
// should execute in that second thread
// ... some code -> executes in main thread
log.deleteInstance(); // join threads
}
Run Code Online (Sandbox Code Playgroud)
我需要提一下,我是线程的新手。我只需要一个想法,这样我就可以开始思考它是如何运作的。
就地lambda可以用于复杂的初始化。因此,您可以执行以下操作:
const widget x = [&]{
widget val; // assume that widget has a default constructor
for (auto i = 2; i <= N; ++i) { // this could be some
val += some_obj.do_something_with(i); // arbitrarily long code
} // needed to initialize x
return val; }();
Run Code Online (Sandbox Code Playgroud)
This is better than writing something like this:
widget x; // should be const, but:
for (auto i = 2; i <= N; ++i) { // this could be some
x += some_obj.do_something_with(i); …Run Code Online (Sandbox Code Playgroud) c++ ×6
c++11 ×3
c++14 ×1
combinations ×1
insert ×1
performance ×1
permutation ×1
stdstring ×1
stl ×1
vector ×1