今天无意间看到VS2012支持current容器,就像比较手动写的线程安全容器与concurrency::concurrent_queue在性能上有什么不一样呢?

先看代码:

#pragma once
#include <queue>
#include <mutex>
#include <thread>

#include "Product.h"

class ProductQueue
{
public:
	static ProductQueue* GetInstance();
	~ProductQueue(void);


	void Put(Product* apProduct);  
	Product* Take();  

private:
	ProductQueue();

private:
	static ProductQueue* m_pInstance;
	std::queue<Product*> m_ProductQueue;
	std::mutex m_Mutex;
};

#include "ProductQueue.h"

ProductQueue* ProductQueue::m_pInstance = nullptr;

ProductQueue::ProductQueue(void)
{
}


ProductQueue::~ProductQueue(void)
{
}

ProductQueue* ProductQueue::GetInstance()
{
	if (nullptr == m_pInstance)
	{
		m_pInstance = new ProductQueue;
	}
	return m_pInstance;
}

void ProductQueue::Put( Product* apProduct )
{
	m_Mutex.lock();
	m_ProductQueue.push(apProduct);
	m_Mutex.unlock();
}

Product* ProductQueue::Take()
{
	m_Mutex.lock(); 
	Product* lpProduct = NULL;  
	if (!m_ProductQueue.empty())  
	{  
		lpProduct = m_ProductQueue.front();  
		m_ProductQueue.pop();  
	}  
	m_Mutex.unlock();  
	return lpProduct;  
}

#pragma once

#include <queue>
#include <concurrent_queue.h>
#include <thread>

#include "Product.h"

class ProductConcurrentQueue
{
public:
	static ProductConcurrentQueue* GetInstance();
	~ProductConcurrentQueue(void);


	void Put(Product* apProduct);  
	Product* Take();  

private:
	ProductConcurrentQueue();

private:
	static ProductConcurrentQueue* m_pInstance;
	concurrency::concurrent_queue<Product*> m_ProductQueue;
};

#include "ProductConcurrentQueue.h"

ProductConcurrentQueue* ProductConcurrentQueue::m_pInstance = nullptr;

ProductConcurrentQueue::ProductConcurrentQueue(void)
{
}


ProductConcurrentQueue::~ProductConcurrentQueue(void)
{
}

ProductConcurrentQueue* ProductConcurrentQueue::GetInstance()
{
	if (nullptr == m_pInstance)
	{
		m_pInstance = new ProductConcurrentQueue;
	}

	return m_pInstance;
}

void ProductConcurrentQueue::Put( Product* apProduct )
{
	m_ProductQueue.push(apProduct);
}

Product* ProductConcurrentQueue::Take()
{
	Product* lpProduct = nullptr;
	m_ProductQueue.try_pop(lpProduct);
	return lpProduct;
}

#pragma once
#include <stdio.h>
#include <string.h>

class Product
{
public:
	Product(int aType,const char* apData)
		:m_Type(aType)
	{
		m_pData = new char[m_Type];
		memcpy(m_pData,apData,aType);
	}

	~Product()
	{
		delete []m_pData;
	}

	int GetSize()
	{
		return m_Type;
	}

	void* GetData()
	{
		return m_pData;
	}

private:
	int m_Type;
	char* m_pData;
};

#include "stdio.h"
#include "Product.h"
#include "ProductConcurrentQueue.h"
#include "ProductQueue.h"
#include <windows.h>

#define Times 1000000
ProductQueue* lpProductQueue = ProductQueue::GetInstance();

ProductConcurrentQueue* lpProductConcurrentQueue = ProductConcurrentQueue::GetInstance();

void Consume1()
{
	for (int i = 0; i < Times; ++i)
	{
		std::string lTest("csdskajdkasdjqkwdnwqjndewjqlelqel,ooasdadas");
		Product* lpProduct = new Product(lTest.size(),lTest.c_str());
		lpProductQueue->Put(lpProduct);

		Product* lpNewProduct = lpProductQueue->Take();
		if (lpNewProduct != nullptr)
		{
			delete lpNewProduct;
			lpNewProduct = nullptr;
		}
	}
}

void Consume2()
{
	for (int i = 0; i < Times; ++i)
	{
		std::string lTest("csdskajdkasdjqkwdnwqjndewjqlelqel,ooasdadas");
		Product* lpProduct = new Product(lTest.size(),lTest.c_str());
		lpProductConcurrentQueue->Put(lpProduct);

		Product* lpNewProduct = lpProductConcurrentQueue->Take();
		if (lpNewProduct != nullptr)
		{
			delete lpNewProduct;
			lpNewProduct = nullptr;
		}
	}
}
int main()
{
	DWORD start, stop;
	start = GetTickCount();
	Consume1();
	printf("consume1 take %lld ms\n", GetTickCount()-start);
	start = GetTickCount();
	Consume2();
	printf("consume2 take %lld ms\n", GetTickCount()-start);
}

迭代1000000时差距是:


这里的Product还是简单的。之后可以进行多线程,复杂Product的测试。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐