zoukankan      html  css  js  c++  java
  • emplace_back VS push_back

    简介

    一直说, emplace_back 比 push_back 快, 我不信, 哈哈~~

    参考链接

    https://blog.csdn.net/yockie/article/details/52674366
    https://www.zhihu.com/question/64493068

    移动构造函数

    using emplace_back avoids the extra copy or move operation required when using push_back(简单来说确实避免了移动构造函数.)
    移动构造函数是C++11带来的std::move强制将左值转为右值, 简单来说就是, 你有一个指针对象, 当使用拷贝构造函数的时候, 消耗太大, 你可以只用移动构造函数, 将指针进行浅拷贝, 然后,就可以了, 这样带来性能的极大提高.

    code

    线上完整代码

    #include <vector>
    #include <string>
    #include "time.hh"
    
    class Foo {
    public:
        Foo(std::string str) : name(str) {
            std::cout << "constructor" << std::endl;
        }
        Foo(const Foo& f) : name(f.name) {
            std::cout << "copy constructor" << std::endl;
        }
        Foo(Foo&& f) : name(std::move(f.name)){
            std::cout << "move constructor" << std::endl;
        }
    
    private:
        std::string name;
    };
    int main() {
    
    
        std::vector<Foo> v;
        int count = 10000000;
        v.reserve(count);       //预分配十万大小,排除掉分配内存的时间
        const int num = 100;
        {
            TIME_INTERVAL_SCOPE("push_back T:");
            Foo temp("ceshi645231");
            for(int i=0; i<num; i++) {
                v.push_back(temp);// push_back(const T&),参数是左值引用
            }
    
            //打印结果:
            //constructor
            //copy constructor
        }
        std::cout << "111111111111111111111
    ";
        v.clear();
        {
            TIME_INTERVAL_SCOPE("push_back move(T):");
            Foo temp("ceshi645321");
            for(int i=0; i<num; i++) {
                
                v.push_back(std::move(temp));// push_back(T &&), 参数是右值引用
            }
    
            //打印结果:
            //constructor
            //move constructor
        }
        std::cout << "222222222222222222222
    ";
        v.clear();
        {
            TIME_INTERVAL_SCOPE("push_back(T&&):");
            for(int i=0; i<num; i++) {
                v.push_back(Foo("ceshi654321"));// push_back(T &&), 参数是右值引用
            }
            
            //打印结果:
            //constructor
            //move constructor
        }
        std::cout << "333333333333333333333
    ";
        v.clear();
        {
            std::string temp = "ceshi123456";
            TIME_INTERVAL_SCOPE("push_back(string):");
            for(int i=0; i<num; i++) {
                v.push_back(temp);// push_back(T &&), 参数是右值引用
            }
            
            //打印结果:
            //constructor
            //move constructor
        }
        std::cout << "444444444444444444444444444
    ";
        v.clear();
        {
            std::string temp = "ceshi123465";
            TIME_INTERVAL_SCOPE("emplace_back(string):");
            for(int i=0; i<num; i++) {
                v.emplace_back(temp);// 只有一次构造函数,不调用拷贝构造函数,速度最快
            }
            //打印结果:
            //constructor
        }
    }
    
    
    #pragma once
    
    #include <iostream>
    #include <memory>
    #include <string>
    #ifdef GCC
    #include <sys/time.h>
    #else
    #include <ctime>
    #endif // GCC
    
    class TimeInterval
    {
    public:
        TimeInterval(const std::string& d) : detail(d)
        {
            init();
        }
    
        TimeInterval()
        {
            init();
        }
    
        ~TimeInterval()
        {
    #ifdef GCC
            gettimeofday(&end, NULL);
            std::cout << detail 
                << 1000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000 
                << " ms" << endl;
    #else
            end = clock();
            std::cout << detail 
                << (double)(end - start) << " ms" << std::endl;
    #endif // GCC
        }
    
    protected:
        void init() {
    #ifdef GCC
            gettimeofday(&start, NULL);
    #else
            start = clock();
    #endif // GCC
        }
    private:
        std::string detail;
    #ifdef GCC
        timeval start, end;
    #else
        clock_t start, end;
    #endif // GCC
    };
    
    #define TIME_INTERVAL_SCOPE(d)   std::shared_ptr<TimeInterval> time_interval_scope_begin = std::make_shared<TimeInterval>(d)
    
    

    测试结果

    constructor
    copy constructor
    ...
    copy constructor
    push_back T:922 ms
    111111111111111111111
    constructor
    move constructor
    ...
    move constructor
    push_back move(T):893 ms
    222222222222222222222
    constructor
    move constructor
    constructor
    ...
    constructor
    move constructor
    constructor
    move constructor
    push_back(T&&):1794 ms
    333333333333333333333
    constructor
    move constructor
    ...
    move constructor
    constructor
    move constructor
    push_back(string):1884 ms
    444444444444444444444444444
    constructor
    ...
    constructor
    emplace_back(string):933 ms
    
    Hope is a good thing,maybe the best of things,and no good thing ever dies.----------- Andy Dufresne
  • 相关阅读:
    sqli-labs Less29-Less31
    sqli-labs Less23-Less28a
    sqli-labs Less20-Less22
    sqli-labs Less17--Less19
    sqli-labs Less13-Less16
    为什么选择centos,而不是Dibian、Ubuntu【转】
    sublime 安装常用插件
    Linux常用命令
    在UEFI下安装windows和Ubuntu双系统目前不可行
    nginx 环境搭建(基于linux)
  • 原文地址:https://www.cnblogs.com/eat-too-much/p/15182648.html
Copyright © 2011-2022 走看看