Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use of std::queue instead of std::vector for outgoing messages #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Olernov
Copy link

@Olernov Olernov commented Jan 17, 2019

More natural for this task and more efficient when removing the first element.

@vinniefalco
Copy link
Owner

I got a question for you, how much memory does std::queue allocate when you insert the first element?

@Olernov
Copy link
Author

Olernov commented Jan 18, 2019

According to https://en.cppreference.com/w/cpp/container/deque: "deques typically have large minimal memory cost; a deque holding just one element has to allocate its full internal array (e.g. 8 times the object size on 64-bit libstdc++; 16 times the object size or 4096 bytes, whichever is larger, on 64-bit libc++)". But is it a problem here? According to another study (https://www.codeproject.com/Articles/5425/An-In-Depth-Study-of-the-STL-Deque-Container) std::deque still shows better performance on push_back()'s and pop_front()'s than std::vector.

@vinniefalco
Copy link
Owner

@pdimov what do you think about this? queue looks correct on paper but vector has its own simplistic charm...

@pdimov
Copy link

pdimov commented Jan 22, 2019

deque/queue is probably better.

#include <vector>
#include <deque>
#include <chrono>
#include <memory>
#include <iostream>

template<class T> void pop_front( std::deque<T> & v )
{
	v.pop_front();
}

template<class T> void pop_front( std::vector<T> & v )
{
	v.erase( v.begin() );
}

template<class V> void test( V&& v, int N, int M )
{
	for( int i = 0; i < M; ++i )
	{
		v.push_back( std::make_shared<int>() );
	}

	auto tp1 = std::chrono::high_resolution_clock::now();

	for( int i = 0; i < N; ++i )
	{
		auto w = v.front();
		pop_front( v );
		v.push_back( w );
	}

	auto tp2 = std::chrono::high_resolution_clock::now();

	std::cout << std::chrono::duration_cast<std::chrono::milliseconds>( tp2 - tp1 ).count() << " ms\n";
}

int main()
{
	int const N = 1000000;
	int const M = 10;

	std::cout << "vector: "; test( std::vector<std::shared_ptr<int>>(), N, M );
	std::cout << " deque: "; test( std::deque<std::shared_ptr<int>>(), N, M );
}

@vinniefalco
Copy link
Owner

Well don't keep me in suspense, where's the output?

@pdimov
Copy link

pdimov commented Jan 22, 2019

N=1000000, M=1:
vector: 31 ms
 deque: 33 ms

N=1000000, M=10:
vector: 52 ms
 deque: 34 ms

N=1000000, M=100:
vector: 282 ms
 deque: 34 ms

N=1000000, M=1000:
vector: 2516 ms
 deque: 33 ms

N=1000000, M=10000:
vector: 25852 ms
 deque: 37 ms

@vinniefalco
Copy link
Owner

Yeah we should use deque/queue... thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants