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;
|
module std::core::dstring;
|
||||||
import std::io;
|
import std::io, std::math;
|
||||||
|
|
||||||
<*
|
<*
|
||||||
The DString offers a dynamic string builder.
|
The DString offers a dynamic string builder.
|
||||||
@@ -648,7 +648,7 @@ fn void DString.reserve(&self, usz addition)
|
|||||||
if (data.capacity >= len) return;
|
if (data.capacity >= len) return;
|
||||||
usz new_capacity = data.capacity * 2;
|
usz new_capacity = data.capacity * 2;
|
||||||
if (new_capacity < MIN_CAPACITY) new_capacity = MIN_CAPACITY;
|
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;
|
data.capacity = new_capacity;
|
||||||
*self = (DString)allocator::realloc(data.allocator, data, StringData.sizeof + 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;
|
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)
|
macro next_power_of_2(x)
|
||||||
{
|
{
|
||||||
$typeof(x) y = 1;
|
if (x <= 1) return 1;
|
||||||
while (y < x) y += y;
|
if (x == 2) return 2;
|
||||||
return y;
|
|
||||||
|
$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
|
macro equals_vec(v1, v2) @private
|
||||||
|
|||||||
Reference in New Issue
Block a user