Skip to content

Commit 3b3a13d

Browse files
committed
perf: avoid allocation if data type is primitive
1 parent d463bfb commit 3b3a13d

1 file changed

Lines changed: 29 additions & 9 deletions

File tree

tuple/include/array_tuple_sketch.hpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222

2323
#include <vector>
2424
#include <memory>
25+
#include <type_traits>
26+
#include <cstring>
27+
#include <algorithm>
2528

2629
#include "serde.hpp"
2730
#include "tuple_sketch.hpp"
@@ -38,18 +41,14 @@ class array {
3841

3942
explicit array(uint8_t size, const T& value, const Allocator& allocator = Allocator()):
4043
allocator_(allocator), size_(size), array_(allocator_.allocate(size_)) {
41-
for (uint8_t i = 0; i < size_; ++i) {
42-
alloc_traits::construct(allocator_, array_ + i, value);
43-
}
44+
init_values(value, std::is_trivially_copyable<T>());
4445
}
4546
array(const array& other):
4647
allocator_(other.allocator_),
4748
size_(other.size_),
4849
array_(allocator_.allocate(size_))
4950
{
50-
for (uint8_t i = 0; i < size_; ++i) {
51-
alloc_traits::construct(allocator_, array_ + i, other.array_[i]);
52-
}
51+
copy_from(other, std::is_trivially_copyable<T>());
5352
}
5453
array(array&& other) noexcept:
5554
allocator_(std::move(other.allocator_)),
@@ -61,9 +60,7 @@ class array {
6160
}
6261
~array() {
6362
if (array_ != nullptr) {
64-
for (uint8_t i = 0; i < size_; ++i) {
65-
alloc_traits::destroy(allocator_, array_ + i);
66-
}
63+
destroy_values(std::is_trivially_destructible<T>());
6764
allocator_.deallocate(array_, size_);
6865
}
6966
}
@@ -90,6 +87,29 @@ class array {
9087
return true;
9188
}
9289
private:
90+
void init_values(const T& value, std::true_type) {
91+
std::fill(array_, array_ + size_, value);
92+
}
93+
void init_values(const T& value, std::false_type) {
94+
for (uint8_t i = 0; i < size_; ++i) {
95+
alloc_traits::construct(allocator_, array_ + i, value);
96+
}
97+
}
98+
void copy_from(const array& other, std::true_type) {
99+
std::copy(other.array_, other.array_ + size_, array_);
100+
}
101+
void copy_from(const array& other, std::false_type) {
102+
for (uint8_t i = 0; i < size_; ++i) {
103+
alloc_traits::construct(allocator_, array_ + i, other.array_[i]);
104+
}
105+
}
106+
void destroy_values(std::true_type) {}
107+
void destroy_values(std::false_type) {
108+
for (uint8_t i = 0; i < size_; ++i) {
109+
alloc_traits::destroy(allocator_, array_ + i);
110+
}
111+
}
112+
93113
Allocator allocator_;
94114
uint8_t size_;
95115
T* array_;

0 commit comments

Comments
 (0)