mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Make Str equality faster
This commit is contained in:
parent
3c74acafa4
commit
ad8fa483d2
1 changed files with 18 additions and 15 deletions
|
@ -105,11 +105,8 @@ pub const RocStr = extern struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eq(self: RocStr, other: RocStr) bool {
|
pub fn eq(self: RocStr, other: RocStr) bool {
|
||||||
const self_bytes_ptr: ?[*]const u8 = self.str_bytes;
|
|
||||||
const other_bytes_ptr: ?[*]const u8 = other.str_bytes;
|
|
||||||
|
|
||||||
// If they are byte-for-byte equal, they're definitely equal!
|
// If they are byte-for-byte equal, they're definitely equal!
|
||||||
if (self_bytes_ptr == other_bytes_ptr and self.str_len == other.str_len) {
|
if (self.str_bytes == other.str_bytes and self.str_len == other.str_len) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,21 +118,27 @@ pub const RocStr = extern struct {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const self_u8_ptr: [*]const u8 = @ptrCast([*]const u8, &self);
|
// Now we have to look at the string contents
|
||||||
const other_u8_ptr: [*]const u8 = @ptrCast([*]const u8, &other);
|
const self_bytes = self.asU8ptr();
|
||||||
const self_bytes: [*]const u8 = if (self.isSmallStr() or self.isEmpty()) self_u8_ptr else self_bytes_ptr orelse unreachable;
|
const other_bytes = other.asU8ptr();
|
||||||
const other_bytes: [*]const u8 = if (other.isSmallStr() or other.isEmpty()) other_u8_ptr else other_bytes_ptr orelse unreachable;
|
|
||||||
|
|
||||||
var index: usize = 0;
|
// It's faster to compare pointer-sized words rather than bytes, as far as possible
|
||||||
|
// The bytes are always pointer-size aligned due to the refcount
|
||||||
// TODO rewrite this into a for loop
|
const self_words = @ptrCast([*]const usize, @alignCast(@alignOf(usize), self_bytes));
|
||||||
const length = self.len();
|
const other_words = @ptrCast([*]const usize, @alignCast(@alignOf(usize), other_bytes));
|
||||||
while (index < length) {
|
var w: usize = 0;
|
||||||
if (self_bytes[index] != other_bytes[index]) {
|
while (w < self_len / @sizeOf(usize)) : (w += 1) {
|
||||||
|
if (self_words[w] != other_words[w]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
index = index + 1;
|
// Compare the leftover bytes
|
||||||
|
var b = w * @sizeOf(usize);
|
||||||
|
while (b < self_len) : (b += 1) {
|
||||||
|
if (self_bytes[b] != other_bytes[b]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue