gpt4 book ai didi

c++ - boost 字符串的分配性能

转载 作者:IT王子 更新时间:2023-10-29 01:06:20 25 4
gpt4 key购买 nike

我将一个 Java GC 测试程序移植到 C++(请参阅下面的代码)以及 Python。 Java 和 Python 的性能比 C++ 好得多,我认为这是因为每次都必须调用 new 来创建字符串。我试过使用 Boost 的 fast_pool_allocator 但实际上性能从 700 毫秒恶化到 1200 毫秒。我是不是使用了错误的分配器,还是我应该做些什么?

编辑:使用 g++ -O3 -march=native --std=c++11 garbage.cpp -lboost_system 编译。 g++ 是版本 4.8.1一次迭代在 Python 中大约需要 300 毫秒,而在 Java 中大约需要 50 毫秒。 std::allocator 提供了大约 700 毫秒,boost::fast_pool_allocator 提供了大约 1200 毫秒。

#include <string>
#include <vector>
#include <chrono>
#include <list>
#include <iostream>
#include <boost/pool/pool_alloc.hpp>
#include <memory>
//#include <gc/gc_allocator.h>


using namespace std;
#include <sstream>
typedef boost::fast_pool_allocator<char> c_allocator;
//typedef std::allocator<char> c_allocator;
typedef basic_string<char, char_traits<char>, c_allocator> pool_string;
namespace patch {
template <typename T> pool_string to_string(const T& in) {
std::basic_stringstream<char, char_traits<char>, c_allocator> stm;
stm << in;
return stm.str();
}
}


#include "mytime.hpp"

class Garbage {
public:
vector<pool_string> outer;
vector<pool_string> old;
const int nThreads = 1;
//static auto time = chrono::high_resolution_clock();

void go() {
// outer.resize(1000000);
//old.reserve(1000000);
auto tt = mytime::msecs();
for (int i = 0; i < 10; ++i) {
if (i % 100 == 0) {
cout << "DOING AN OLD" << endl;
doOld();
tt = mytime::msecs();
}

for (int j = 0; j < 1000000/nThreads; ++j)
outer.push_back(patch::to_string(j));

outer.clear();
auto t = mytime::msecs();
cout << (t - tt) << endl;
tt = t;
}
}

void doOld() {
old.clear();
for (int i = 0; i < 1000000/nThreads; ++i)
old.push_back(patch::to_string(i));
}
};

int main() {
Garbage().go();
}

最佳答案

问题是您每次都使用新的字符串流来转换整数。

修复它:

namespace patch {
template <typename T> pool_string to_string(const T& in) {
return boost::lexical_cast<pool_string>(in);
}
}

现在的时间是:

DOING AN OLD
0.175462
0.0670085
0.0669926
0.0687969
0.0692518
0.0669318
0.0669196
0.0669187
0.0668962
0.0669185

real 0m0.801s
user 0m0.784s
sys 0m0.016s

查看 Live On Coliru

完整代码供引用:

#include <boost/pool/pool_alloc.hpp>
#include <chrono>
#include <iostream>
#include <list>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include <boost/lexical_cast.hpp>
//#include <gc/gc_allocator.h>

using string = std::string;

namespace patch {
template <typename T> string to_string(const T& in) {
return boost::lexical_cast<string>(in);
}
}

class Timer
{
typedef std::chrono::high_resolution_clock clock;
clock::time_point _start;
public:
Timer() { reset(); }
void reset() { _start = now(); }
double elapsed()
{
using namespace std::chrono;
auto e = now() - _start;
return duration_cast<nanoseconds>(e).count()*1.0e-9;
}
clock::time_point now()
{
return clock::now();
}
};


class Garbage {
public:
std::vector<string> outer;
std::vector<string> old;
const int nThreads = 1;

void go() {
outer.resize(1000000);
//old.reserve(1000000);
Timer timer;

for (int i = 0; i < 10; ++i) {
if (i % 100 == 0) {
std::cout << "DOING AN OLD" << std::endl;
doOld();
}

for (int j = 0; j < 1000000/nThreads; ++j)
outer.push_back(patch::to_string(j));

outer.clear();
std::cout << timer.elapsed() << std::endl;
timer.reset();
}
}

void doOld() {
old.clear();
for (int i = 0; i < 1000000/nThreads; ++i)
old.push_back(patch::to_string(i));
}
};

int main() {
Garbage().go();
}

关于c++ - boost 字符串的分配性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23188356/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com