2014-05-17 26 views
22

Ben emplace_back kazanan olacağını düşündük, böyle bir şey yaparken: kopyalamak olurdu, sonra vektör hemen nesneyi inşa edecek push_back ederken, ilk anonim nesne inşa edecek veNeden emplace_back, push_back'den daha hızlıdır?

v.push_back(myClass(arg1, arg2)); 

emplace_back çünkü vektör Daha fazla bilgi için this numaralı soruya bakın.

Google ayrıca this ve this soruları verir.

Onları tamsayılarla doldurulacak bir vektör için karşılaştırmaya karar verdim.

#include <iostream> 
#include <vector> 
#include <ctime> 
#include <ratio> 
#include <chrono> 

using namespace std; 
using namespace std::chrono; 

int main() { 

    vector<int> v1; 

    const size_t N = 100000000; 

    high_resolution_clock::time_point t1 = high_resolution_clock::now(); 
    for(size_t i = 0; i < N; ++i) 
    v1.push_back(i); 
    high_resolution_clock::time_point t2 = high_resolution_clock::now(); 

    duration<double> time_span = duration_cast<duration<double>>(t2 - t1); 

    std::cout << "push_back took me " << time_span.count() << " seconds."; 
    std::cout << std::endl; 

    vector<int> v2; 

    t1 = high_resolution_clock::now(); 
    for(size_t i = 0; i < N; ++i) 
    v2.emplace_back(i); 
    t2 = high_resolution_clock::now(); 
    time_span = duration_cast<duration<double>>(t2 - t1); 
    std::cout << "emplace_back took me " << time_span.count() << " seconds."; 
    std::cout << std::endl; 

    return 0; 
} 

sonuç emplace_back daha hızlı olmasıdır: Burada

deney kodudur.

push_back took me 2.76127 seconds. 
emplace_back took me 1.99151 seconds. 

Neden? 1. bağlantılı sorunun cevabı açıkça bir performans farkı olmayacağını söylüyor.

Ayrıca diğer time methods pesudo sitemden ama aynı sonuçları denedim.

[EDIT] Yorumlar, int s ile sınamanın hiçbir şey söylemediğini ve push_back bir ref aldığını söylüyor.

Yukarıdaki kodda aynı test yaptım, ancak bunun yerine int arasında Dersim A vardı:

class A { 
public: 
    A(int a) : a(a) {} 
private: 
    int a; 
}; 

Sonuç:

push_back took me 6.92313 seconds. 
emplace_back took me 6.1815 seconds. 

[EDIT.2]

Farklı denlan, operasyonların pozisyonunu da değiştirmem gerektiğini söyledi, bu yüzden onları değiştirdim ve her iki durumda da (int ve class A), emplace_back yine kazanan oldu.

[ÇÖZÜM]

I ölçümleri geçersiz kılan debug mode kodu, çalışan. Kıyaslama için her zaman kodu release mode'da çalıştırın.

cevap

37

Test vakanız çok yardımcı olmuyor. push_back bir kap elemanını alır ve bunu kabın içine kopyalar/taşır. emplace_back, yeni bir konteyner öğesinden gelen rastgele argümanlar ve yapılar alır. Ancak, zaten emplace_back öğesinin türü olan tek bir bağımsız değişken iletirseniz, kopyala/taşı yapıcıyı zaten kullanabilirsiniz.

İşte daha iyi bir karşılaştırma var:

Foo x; Bar y; Zip z; 

v.push_back(T(x, y, z)); // make temporary, push it back 
v.emplace_back(x, y, z); // no temporary, directly construct T(x, y, z) in place 

önemli fark ise emplace_backaçık dönüşüm işlemleri gerçekleştirir olmasıdır: sizi

std::vector<std::unique_ptr<Foo>> v; 
v.emplace_back(new Foo(1, 'x', true)); // constructor is explicit! 

Bu örnek gelecekte hafif yapmacık olacak v.push_back(std::make_unique<Foo>(1, 'x', true)) deme. Ancak, diğer yapılar da emplace ile çok iyi:

std::vector<std::thread> threads; 
threads.emplace_back(do_work, 10, "foo"); // call do_work(10, "foo") 
threads.emplace_back(&Foo::g, x, 20, false); // call x.g(20, false)