C11性能之道:标准库优化

Posted 渔舟唱晚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C11性能之道:标准库优化相关的知识,希望对你有一定的参考价值。

1、emplace_back减少内存拷贝和移动

  emplace_back能通过参数构造对象,不需要拷贝或者移动内存,相比pusk_back能更好的避免内存的拷贝和移动,使容器插入元素性能得到进一步提升。几乎所有的标准库容器都增加了类型的方法:emplace,emplace_hint,emplace_front,emplace_after和emplace_back。

  基本用法:

#include <iostream>
#include <vector>

using namespace std;

struct A 
{
    int x;
    double y;
    A(int a, double b): x(a), y(b){}
};

int main()
{
    vector<A> v;
    v.emplace_back(1, 2.0);
    
    cout << v.size() << endl;
    
    return 0;
}

  用法还是很简单的,直接通过构造函数的参数就可以构造对象,当然,要求对象有相应的构造函数,如果没有构造函数会报错。

  emplace_back相对push_back更有性能优势。

#include <iostream>
#include <vector>
#include <map>

using namespace std;

struct A 
{
    int x;
    double y;
    string name;
    
    A(int a, double b, string c):x(a), y(b), name(c)
    {
        cout << "construct" << endl;
    }
    
    A(const A &a): x(a.x), y(a.y), name(std::move(a.name))
    {
        cout << "move" << endl;
    }
};

int main()
{
    map<int, A> m;
    int i = 4;
    double d = 2.0;
    string s = "C++11";

    cout << "--insert--" << endl;
    m.insert(make_pair(2, A(i, d, s)));
    
    cout << "--emplace--" << endl;
    m.emplace(1, A(i, d, s));
    
    vector<A> v;
    cout << "--emplace_back--" << endl;
    v.emplace_back(i, d, s);
    
    cout << "--push_back--" << endl;
    v.push_back(A(i, d, s));
    
    return 0;
}

//执行结果:
--insert--                             
construct                              
move                                   
move                                   
--emplace--                            
construct                              
move                                   
--emplace_back--                       
construct                              
--push_back--                          
construct                              
move                                   
move 

  可以看出不管map还是vector,emplace系列方法在性能上面都优于之前的方法,所以尽可能的使用emplace系列方法,不过前提是类型必须有相应的构造函数。

2、unordered container无序容器

  c++11提供了无序容器unordered_map/unordered_multimap和unordered_set/unordered_multiset,由于这些容器中的元素是不排序的,所以性能高于map/multimap和set/multiset。map和set是红黑树,在插入元素时会自动排序,而无序容器内部是散列表,通过hash,而不是排序来快速操作元素,使得效率更高。

  对于自定义类型,无序容器的key需要提供hash_value函数,其他用法和map/set的用法是一样的。不过对于自定义的key,需要提供hash函数和比较函数。

  对于基本类型来说,不需要提供hash函数和比较函数,用法和map/set一样。

以上是关于C11性能之道:标准库优化的主要内容,如果未能解决你的问题,请参考以下文章

C11简洁之道:类型推导

C11简洁之道:函数绑定

C11简洁之道:模板改进

C11简洁之道:lambda表达式

第一章 C语言编程

MySQL性能优化之道