![](/img/trans.png)
[英]C++ - passing references to std::shared_ptr or boost::shared_ptr
[英]Which is faster on Visual C++ 2010 - std::shared_ptr or boost::shared_ptr?
有沒有人在發布模式版本中測試過這個? 或者實現如此相似,沒有顯着差異?
我對速度感興趣:
創建一個新的shared_ptr
創建shared_ptr的副本
取消引用指針以訪問指針對象
這將是針對速度優化的發布版本,使用make_shared()創建新的shared_ptrs
好的,所以看起來沒有人這樣做過。 以下是我使用WIN32控制台應用程序的標准VC 10優化設置找到的內容:
當填充1000萬個指針條目的向量時,Visual C ++ 2010 SP1 std :: make_shared和std :: shared_ptr比Boost 1.46.1當量更快(1.96秒與20次運行中平均0.92秒)
復制1000萬個指針條目的數組時,Boost 1.46.1比Visual C ++ 2010 SP1快一點(0.15秒與20次運行平均0.17秒)
當取消引用1000萬個指針條目的向量20次時,Visual C ++ 2010 SP1略高於Boost 1.46.1當量(0.72秒,而20次運行平均為0.811秒)
結論:創建shared_ptrs以填充向量時存在顯着差異。 與Boost 1.46.1相比,Visual C ++ 2010 shared_ptr幾乎快了兩倍,表明實現上有很大差異。
其他測試沒有顯示出顯着差異。
這是我使用的代碼:
#include "stdafx.h"
struct A
{
A( const unsigned A) : m_value(A)
{
}
const unsigned m_value;
};
typedef std::shared_ptr<A> APtr;
typedef boost::shared_ptr<A> ABoostPtr;
double TestSTLCreateSpeed()
{
const unsigned NUM_ENTRIES = 10000000;
std::vector<APtr> buffer;
buffer.reserve(NUM_ENTRIES);
boost::timer timer;
for( unsigned nEntry = 0; nEntry < NUM_ENTRIES; ++nEntry)
{
buffer.emplace_back( std::make_shared<A>(nEntry) );
}
const double timeTaken = timer.elapsed();
std::cout << "STL create test took " << timeTaken << " secs.\r\n";
return timeTaken;
}
double BoostSTLCreateSpeed()
{
const unsigned NUM_ENTRIES = 10000000;
std::vector<ABoostPtr> buffer;
buffer.reserve(NUM_ENTRIES);
boost::timer timer;
for( unsigned nEntry = 0; nEntry < NUM_ENTRIES; ++nEntry)
{
buffer.emplace_back( boost::make_shared<A>(nEntry) );
}
const double timeTaken = timer.elapsed();
std::cout << "BOOST create test took " << timeTaken << " secs.\r\n";
return timeTaken;
}
double TestSTLCopySpeed()
{
const unsigned NUM_ENTRIES = 10000000;
std::vector<APtr> buffer;
buffer.reserve(NUM_ENTRIES);
for( unsigned nEntry = 0; nEntry < NUM_ENTRIES; ++nEntry)
{
buffer.emplace_back( std::make_shared<A>(nEntry) );
}
boost::timer timer;
std::vector<APtr> buffer2 = buffer;
const double timeTaken = timer.elapsed();
std::cout << "STL copy test took " << timeTaken << " secs.\r\n";
return timeTaken;
}
double TestBoostCopySpeed()
{
const unsigned NUM_ENTRIES = 10000000;
std::vector<ABoostPtr> buffer;
buffer.reserve(NUM_ENTRIES);
for( unsigned nEntry = 0; nEntry < NUM_ENTRIES; ++nEntry)
{
buffer.emplace_back( boost::make_shared<A>(nEntry) );
}
boost::timer timer;
std::vector<ABoostPtr> buffer2 = buffer;
const double timeTaken = timer.elapsed();
std::cout << "BOOST copy test took " << timeTaken << " secs.\r\n";
return timeTaken;
}
double TestBoostDerefSpeed()
{
const unsigned NUM_ENTRIES = 10000000;
std::vector<ABoostPtr> buffer;
buffer.reserve(NUM_ENTRIES);
for( unsigned nEntry = 0; nEntry < NUM_ENTRIES; ++nEntry)
{
buffer.emplace_back( boost::make_shared<A>(nEntry) );
}
boost::timer timer;
unsigned total = 0;
for(unsigned nIter = 0; nIter < 20; ++nIter)
{
std::for_each( buffer.begin(), buffer.end(),
[&](const ABoostPtr& pA){
total += pA->m_value;
});
}
const double timeTaken = timer.elapsed();
std::cout << "BOOST deref total = " << total << ".\r\n";
std::cout << "BOOST deref test took " << timeTaken << " secs.\r\n";
return timeTaken;
}
double TestSTLDerefSpeed()
{
const unsigned NUM_ENTRIES = 10000000;
std::vector<APtr> buffer;
buffer.reserve(NUM_ENTRIES);
for( unsigned nEntry = 0; nEntry < NUM_ENTRIES; ++nEntry)
{
buffer.emplace_back( std::make_shared<A>(nEntry) );
}
boost::timer timer;
unsigned total = 0;
for(unsigned nIter = 0; nIter < 20; ++nIter)
{
std::for_each( buffer.begin(), buffer.end(),
[&](const APtr& pA){
total += pA->m_value;
});
}
const double timeTaken = timer.elapsed();
std::cout << "STL deref total = " << total << ".\r\n";
std::cout << "STL deref test took " << timeTaken << " secs.\r\n";
return timeTaken;
}
int _tmain(int argc, _TCHAR* argv[])
{
double totalTime = 0.0;
const unsigned NUM_TESTS = 20;
totalTime = 0.0;
for ( unsigned nTest = 0; nTest < NUM_TESTS; ++nTest)
{
totalTime += BoostSTLCreateSpeed();
}
std::cout << "BOOST create test took " << totalTime / NUM_TESTS << " secs average.\r\n";
totalTime = 0.0;
for ( unsigned nTest = 0; nTest < NUM_TESTS; ++nTest)
{
totalTime += TestSTLCreateSpeed();
}
std::cout << "STL create test took " << totalTime / NUM_TESTS << " secs average.\r\n";
totalTime = 0.0;
for ( unsigned nTest = 0; nTest < NUM_TESTS; ++nTest)
{
totalTime += TestBoostCopySpeed();
}
std::cout << "BOOST copy test took " << totalTime / NUM_TESTS << " secs average.\r\n";
totalTime = 0.0;
for ( unsigned nTest = 0; nTest < NUM_TESTS; ++nTest)
{
totalTime += TestSTLCopySpeed();
}
std::cout << "STL copy test took " << totalTime / NUM_TESTS << " secs average.\r\n";
totalTime = 0.0;
for ( unsigned nTest = 0; nTest < NUM_TESTS; ++nTest)
{
totalTime += TestBoostDerefSpeed();
}
std::cout << "Boost deref test took " << totalTime / NUM_TESTS << " secs average.\r\n";
totalTime = 0.0;
for ( unsigned nTest = 0; nTest < NUM_TESTS; ++nTest)
{
totalTime += TestSTLDerefSpeed();
}
std::cout << "STL deref test took " << totalTime / NUM_TESTS << " secs average.\r\n";
return 0;
}
我會等待一段時間,如果沒有人反駁我的結果或得出更好的結論,我會接受我自己的答案。
VS10的版本在可能的情況下使用rvalue引用並移動語義,因此原則上它優先於Boost C ++ 98實現。 你可能需要相當努力地創建一個顯示出顯着實際差異的程序,但是......但是要試一試。 另外不要忘記std::make_shared
,這是C ++ 0x中的新功能,這要歸功於轉發。
更新:在任何情況下,取消引用和復制幾乎都是相同的。 也許在自定義刪除器和分配器的存儲方式以及make_shared的實現方式方面存在一些有趣的差異。 讓我查一下來源。
更新2 :有趣的是,使用可變參數模板和右值引用的Boost版本看起來肯定比VS10版本更好,因為VS10沒有可變參數模板,並且必須使用可怕的黑色藝術來偽造這種行為。 但這完全是一個編譯時問題,所以它並不重要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.