Why is my valarray faster than std::valarray

Hi, I just created some kind of valarray only with some operations such as +,*,[]. It was just an exercise to test how fast std::valarray is. I read that its madly optimized for speed. So I tested them doing the same operation
4 * (x + y) + z over 1m times and timed them.
On my laptop it took 15 sec for my valarray to complete this task but it took 18 sec for std::valarray to complete the same task.

What might be the reason for this. I feel like I'm maybe missing some important part that I should be adding to my code. I dont expect you guys to go through all the code but maybe you might tell why do you think this is happening without even looking at it.

PS : tried to post the code as well here but its too long.
Does your valarray come with all the functionality of std::valarray?
Here it is. I dont have some kind of exception guarantees. Just made some functions so I can faster make this speed comparison.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
template<typename T, typename alloc = std::allocator<T>>
class array_base
{
public:
	alloc a;
	T* elem;
	T* last;
	std::size_t size;


	array_base(const array_base&);
	array_base& operator=(const array_base&);

	array_base(array_base&&);
	array_base& operator=(array_base&&);

	void destroy();
	void resize(std::size_t sz);

	template<typename... Args>
	Enable_if<std::is_constructible<T, Args...>::value> construct(std::size_t pos, Args... args);

	array_base(std::size_t sz, alloc aa = alloc{}) 
		: a{ aa }, elem{ a.allocate(sz) }, last{elem + sz}, size {sz} {}

	~array_base() { a.deallocate(elem, size); }
};


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
template<typename T, typename alloc = std::allocator<T>>
class val_array
{

	array_base<T, alloc> base;
public:
	val_array(std::size_t sz, T val = {});
	val_array(std::initializer_list<T>);

	val_array(const val_array&);
	val_array& operator=(const val_array&);

	val_array(val_array&&);
	val_array& operator=(val_array&&);

	unsigned size() const { return base.size; }

	T& operator[](std::size_t sz);
	const T& operator[](std::size_t sz) const;

	
	template<typename U, typename A>
	val_array<std::common_type_t<T, U>, common_allocator<T, U, alloc, A>> operator+(const val_array<U, A>& v) const;
	
	template<typename U>
	val_array<std::common_type_t<T, U>, get_allocator<T,U,alloc>> operator+(U val) const;

	template<typename U, typename A>
	val_array<std::common_type_t<T, U>, common_allocator<T, U, alloc, A>> operator*(const val_array<U,A>& v) const;

	template<typename U>
	val_array<std::common_type_t<T, U>, get_allocator<T, U, alloc>> operator*(U val) const;

	~val_array() { base.destroy(); }
};


EDIT : here are some of those operations

1
2
3
4
5
6
7
8
9
10
11
12
template<typename T, typename alloc>
template<typename U>
val_array<std::common_type_t<T, U>, get_allocator<T,U,alloc>> val_array<T, alloc>::operator*(U val)const
{
	unsigned sz = size();
	val_array<std::common_type_t<T, U>, get_allocator<T, U, alloc>> temp(sz);
	for (unsigned i = 0; i < sz; ++i)
	{
		temp[i] = this->operator[](i) * val;
	}
	return temp;
}

1
2
3
4
5
6
7
8
9
10
11
12
template<typename T, typename alloc>
template<typename U, typename A>
val_array<std::common_type_t<T, U>, common_allocator<T, U, alloc, A>> val_array<T, alloc>::operator*(const val_array<U, A>& v)const
{
	unsigned sz = size();
	val_array<std::common_type_t<T, U>, common_allocator<T, U, alloc, A>> temp(sz);
	for (unsigned i = 0; i < sz; ++i)
	{
		temp[i] = this->operator[](i) * v[i];
	}
	return temp;
}
Last edited on
Topic archived. No new replies allowed.