原本是没打算写一个系列的,结果到了第二篇才开始写一个前言,本来不确定自己会测试哪些东西,哪些内容,以及有没有时间持续写这些比较偏的内容,但既然有打算写第二篇了,那么就写一个系列吧。本系列主要是QT和c++一些对比,当然也可能会有本篇这种纯c++的测试,看情况吧只能说。测到哪里写到哪里,时间就不太好说了= =。
序
对于std::function和std::bind不太了解的话,建议先百度掌握下,比较简单,这里就不展开引入了,如果以后有时间的话可能会出一个文章来介绍。但是本篇这里的话,就直接进入正题查看结果。
测试环境:Qt5.7,vs2015。
测试结果
本次结果主要目的是测试函数通过std::function——将函数绑定后调用和正常通过对象调用的效率,本次测试10000次循环调用,分别包含各种情况下的参数的测试。如下图所示:
测试数据解释:
正常调用:
直接通过对象调用成员函数的形式调用该函数。
Std::function可变参:
即通过可变参方式调用std::function对象,也相当于多包了一层。如下图所示:
Std::function直接调用:
即不通过该函数,直接调用_Func传递参数。
测试结果总结:
总览:
调用速度率(横向):
直接调用>std::function(无参数和int类型时,三者接近)。
参数速度(纵向):
正常调用:
无参数≈int参数≈指针≈引用>右值引用>=(≈)值传递。
std::function直接调用:
无参数≈int参数≈指针≈引用>右值引用>值传递。
std::function可变参:
无参数≈int参数≈指针>引用>右值引用>值传递。
总结与分析
原因分析:
首先解释下再通过可变参调用且参数是引用时,为什么他的效率比指针传参更慢许多,理论上来说两种传递方式的效率是一样,但是注意的是,因为是可变参,这个string在传递的时候,该函数不知道是引用,直接当成对象传递,所以经过了一层拷贝构造,也就导致他的引用传递的测试,与另外两者的测试相比差距有点大。当然,如果要解决这个问题,使用std::ref即可。
指针和引用在传参时,直接传递,不需要经过拷贝,所以效率上可能稍快。而右值引用和值传递在传参时,分别会调用move构造函数和拷贝构造函数,所以效率上可能会稍慢。
另外,传右值引用和传值时,正常调用不会有太大效率差距,同事指出,这可能是编译器优化的结果,默认传值还是调用move构造,而使用function因为饶了一层,编译器没法优化。
而在std::function的结果里,move构造函数的效率较拷贝构造函数高一丢丢,大致(这句话是我的理解,只供参考,如有错误,可以提出探讨)是因为,move构造函数直接把右值引用的内存拿来用,也就是直接拷贝指针,将原来指针置空,而不是自己开辟内存,而拷贝构造会申请内存,然后memcpy。如果不了解move构造函数,我在另一篇文章中写了: 传送门
总体而言,是符合对象模型的,为求效率,函数传参时最好使用引用和指针,其次move,最后传值。
2839

被折叠的 条评论
为什么被折叠?



