stdlib: optimize math::next_power_of_2 to O(1) using hardware CLZ (#2839)

* stdlib: optimize math::next_power_of_2 to O(1) using hardware CLZ

- updated DString.reserve to use this

* bit smearing

---------

Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
Manu Linares
2026-01-30 20:20:58 -03:00
committed by GitHub
parent 373013046d
commit 1b7601fdbb
2 changed files with 23 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
module std::core::dstring;
import std::io;
import std::io, std::math;
<*
The DString offers a dynamic string builder.
@@ -648,7 +648,7 @@ fn void DString.reserve(&self, usz addition)
if (data.capacity >= len) return;
usz new_capacity = data.capacity * 2;
if (new_capacity < MIN_CAPACITY) new_capacity = MIN_CAPACITY;
while (new_capacity < len) new_capacity *= 2;
if (new_capacity < len) new_capacity = math::next_power_of_2(len);
data.capacity = new_capacity;
*self = (DString)allocator::realloc(data.allocator, data, StringData.sizeof + new_capacity);
}

View File

@@ -997,11 +997,29 @@ macro bool is_power_of_2(x)
return x != 0 && (x & (x - 1)) == 0;
}
<*
Returns the next power of two that is greater than or equal to x.
@require types::is_int($typeof(x)) : "Input must be an integer type"
@require x >= 0 : "Input must be non-negative"
*>
macro next_power_of_2(x)
{
$typeof(x) y = 1;
while (y < x) y += y;
return y;
if (x <= 1) return 1;
if (x == 2) return 2;
$typeof(x) v = x - 1;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
$if ($sizeof(x) >= 2): v |= v >> 8; $endif;
$if ($sizeof(x) >= 4): v |= v >> 16; $endif;
$if ($sizeof(x) >= 8): v |= v >> 32; $endif;
$if ($sizeof(x) >= 16): v |= v >> 64; $endif;
return v + 1;
}
macro equals_vec(v1, v2) @private