Merge pull request #103759 from Ivorforce/zero-constructible

Optimize `Array.resize` by using `memset` (through new `is_zero_constructible` type trait)
This commit is contained in:
Thaddeus Crews 2025-03-12 10:31:55 -05:00
commit 74907876d3
No known key found for this signature in database
GPG key ID: 62181B86FE9E5D84
19 changed files with 93 additions and 11 deletions

View file

@ -34,6 +34,7 @@
#include "core/templates/safe_refcount.h"
#include <stddef.h>
#include <cstring>
#include <new>
#include <type_traits>
@ -195,6 +196,22 @@ T *memnew_arr_template(size_t p_elements) {
return (T *)mem;
}
// Fast alternative to a loop constructor pattern.
template <bool p_ensure_zero = false, typename T>
_FORCE_INLINE_ void memnew_arr_placement(T *p_start, size_t p_num) {
if constexpr (std::is_trivially_constructible_v<T> && !p_ensure_zero) {
// Don't need to do anything :)
} else if constexpr (is_zero_constructible_v<T>) {
// Can optimize with memset.
memset(static_cast<void *>(p_start), 0, p_num * sizeof(T));
} else {
// Need to use a for loop.
for (size_t i = 0; i < p_num; i++) {
memnew_placement(p_start + i, T);
}
}
}
/**
* Wonders of having own array functions, you can actually check the length of
* an allocated-with memnew_arr() array