mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user