• C++前后自增效率分析


    1、前自增/后自增操作符示例

    class Integer
    {
    public:
    	// ++i  first +1,then return new value
    	Integer &operator++()
    	{
    		value_ += 1;
    		return *this;
    	}
    
    	// i++  first save old value,then +1,last return old value
    	Integer operator++(int)
    	{
    		Integer old = *this;
    		value_ += 1;
    		return old;
    	}
    
    private:
    	int value_;
    };
    

    2、分别基于内置数据类型和自定义数据类型做测试

    #include <iostream>
    #include <vector>
    #include <windows.h>
    
    int main()
    {
    	const int sizeInt = 0x00fffffe;
    	const int sizeVec = 0x000ffffe;
    
    	LARGE_INTEGER frequency;
    	QueryPerformanceFrequency(&frequency);
    
    	{
    		int* testValue = new int[sizeInt];
    
    		LARGE_INTEGER start;
    		LARGE_INTEGER stop;
    		QueryPerformanceCounter(&start);
    		for (int i = 0; i < sizeInt; ++i)
    		{
    			testValue[i]++;
    		}
    		QueryPerformanceCounter(&stop);		
    
    		const auto interval = static_cast<double>(stop.QuadPart - start.QuadPart);
    		const auto timeSpan = interval / frequency.QuadPart * 1000.0; //ms
    		std::cout << "i++ " << sizeInt << " times takes " << timeSpan << "ms." << std::endl;
    
    		delete[] testValue;
    	}
    	{
    		int* testValue = new int[sizeInt];
    
    		LARGE_INTEGER start;
    		LARGE_INTEGER stop;
    		QueryPerformanceCounter(&start);
    		for (int i = 0; i < sizeInt; ++i)
    		{
    			++testValue[i];
    		}
    		QueryPerformanceCounter(&stop);		
    
    		const auto interval = static_cast<double>(stop.QuadPart - start.QuadPart);
    		const auto timeSpan = interval / frequency.QuadPart * 1000.0; //ms
    		std::cout << "++i " << sizeInt << " times takes " << timeSpan << "ms." << std::endl;
    
    		delete[] testValue;
    	}
    
    	{
    		const std::vector<int> testVec(sizeVec);
    		LARGE_INTEGER start;
    		LARGE_INTEGER stop;
    		QueryPerformanceCounter(&start);
    		for (auto iter = testVec.cbegin(); iter != testVec.cend(); iter++)
    		{
    		}
    		QueryPerformanceCounter(&stop);
    
    		const auto interval = static_cast<double>(stop.QuadPart - start.QuadPart);
    		const auto timeSpan = interval / frequency.QuadPart * 1000.0; //ms
    		std::cout << "iterator++ " << sizeVec << " times takes " << timeSpan << "ms." << std::endl;
    	}
    	{
    		const std::vector<int> testVec(sizeVec);
    		LARGE_INTEGER start;
    		LARGE_INTEGER stop;
    		QueryPerformanceCounter(&start);
    		for (auto iter = testVec.cbegin(); iter != testVec.cend(); ++iter)
    		{
    		}
    		QueryPerformanceCounter(&stop);
    
    		const auto interval = static_cast<double>(stop.QuadPart - start.QuadPart);
    		const auto timeSpan = interval / frequency.QuadPart * 1000.0; //ms
    		std::cout << "++iterator " << sizeVec << " times takes " << timeSpan << "ms." << std::endl;
    	}
    
    	return 0;
    }
    

    3、五次执行结果

    4、结果分析及结论

    从上面的执行结果可以看出来,对int类型的测试中前自增和后自增耗费时间基本不变;而对std::vector中iterator的测试显示,前自增所耗费的时间几乎是后自增的一半。这是因为,在后自增的操作中,会首先生成原始对象的一个副本,然后将副本中的值加1后返回给调用者,这样一来每执行一次后自增操作,就会增加一个对象副本,效率自然降低了。

    因此可以得出结论:对于C++内置类型的自增而言,前自增、后自增的效率相差不大;对于自定义类型(类、结构体)的自增操作而言,前自增的效率几乎比后自增大一倍。

    5、注意事项

    上述试验的循环代码如果在Release模式下会被C++编译器优化掉,因此需要在Debug模式下才能获得预期效果,但在实际项目中大概率是不会被编译器优化的。

  • 相关阅读:
    CSS中属性Padding的参数个数定义(转)
    动态加载js
    jquery解决图片路径不存在
    jquery插件
    js 判断 undefined
    (转)ExtJS4 Grid1学习1
    ExtJS4 表单Form Panel
    浏览器标题 闪烁效果
    C#正则表达式 委托替换
    简单服务器端控件 Simple Server Control
  • 原文地址:https://www.cnblogs.com/xhubobo/p/12778403.html
Copyright © 2020-2023  润新知