mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
[internal] Make string comparisons faster
This commit is contained in:
@@ -166,7 +166,22 @@ pub inline fn lastIndexOf(self: string, str: string) ?usize {
|
||||
}
|
||||
|
||||
pub inline fn indexOf(self: string, str: string) ?usize {
|
||||
return std.mem.indexOf(u8, self, str);
|
||||
const self_ptr = self.ptr;
|
||||
const self_len = self.len;
|
||||
|
||||
const str_ptr = str.ptr;
|
||||
const str_len = str.len;
|
||||
|
||||
// > Both old and new libc's have the bug that if needle is empty,
|
||||
// > haystack-1 (instead of haystack) is returned. And glibc 2.0 makes it
|
||||
// > worse, returning a pointer to the last byte of haystack. This is fixed
|
||||
// > in glibc 2.1.
|
||||
if (self_len == 0 or str_len == 0 or self_len < str_len)
|
||||
return null;
|
||||
|
||||
const start = bun.C.memmem(self_ptr, self_len, str_ptr, str_len) orelse return null;
|
||||
|
||||
return @ptrToInt(start) - @ptrToInt(self_ptr);
|
||||
}
|
||||
|
||||
// --
|
||||
@@ -729,58 +744,73 @@ pub fn eqlCaseInsensitiveASCII(a: string, comptime b: anytype, comptime check_le
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn eqlLong(a_: string, b: string, comptime check_len: bool) bool {
|
||||
pub fn eqlLong(a_str: string, b_str: string, comptime check_len: bool) bool {
|
||||
const len = b_str.len;
|
||||
|
||||
if (comptime check_len) {
|
||||
if (a_.len == 0) {
|
||||
return b.len == 0;
|
||||
if (len == 0) {
|
||||
return a_str.len == 0;
|
||||
}
|
||||
|
||||
if (a_.len != b.len) {
|
||||
if (a_str.len != len) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
std.debug.assert(b_str.len == a_str.len);
|
||||
}
|
||||
|
||||
const len = b.len;
|
||||
var dword_length = b.len >> 3;
|
||||
var b_ptr: usize = 0;
|
||||
const a = a_.ptr;
|
||||
const end = b_str.ptr + len;
|
||||
var a = a_str.ptr;
|
||||
var b = b_str.ptr;
|
||||
|
||||
while (dword_length > 0) : (dword_length -= 1) {
|
||||
const slice = b.ptr;
|
||||
if (@bitCast(usize, a[b_ptr..len][0..@sizeOf(usize)].*) != @bitCast(usize, (slice[b_ptr..b.len])[0..@sizeOf(usize)].*))
|
||||
return false;
|
||||
b_ptr += @sizeOf(usize);
|
||||
if (b_ptr == b.len) return true;
|
||||
if (a == b)
|
||||
return true;
|
||||
|
||||
{
|
||||
var dword_length = len >> 3;
|
||||
while (dword_length > 0) : (dword_length -= 1) {
|
||||
if (@bitCast(usize, a[0..@sizeOf(usize)].*) != @bitCast(usize, b[0..@sizeOf(usize)].*))
|
||||
return false;
|
||||
b += @sizeOf(usize);
|
||||
if (b == end) return true;
|
||||
a += @sizeOf(usize);
|
||||
}
|
||||
}
|
||||
|
||||
if (comptime @sizeOf(usize) == 8) {
|
||||
if ((len & 4) != 0) {
|
||||
const slice = b.ptr;
|
||||
if (@bitCast(u32, a[b_ptr..len][0..@sizeOf(u32)].*) != @bitCast(u32, (slice[b_ptr..b.len])[0..@sizeOf(u32)].*))
|
||||
if (@bitCast(u32, a[0..@sizeOf(u32)].*) != @bitCast(u32, b[0..@sizeOf(u32)].*))
|
||||
return false;
|
||||
|
||||
b_ptr += @sizeOf(u32);
|
||||
|
||||
if (b_ptr == b.len) return true;
|
||||
b += @sizeOf(u32);
|
||||
if (b == end) return true;
|
||||
a += @sizeOf(u32);
|
||||
}
|
||||
}
|
||||
|
||||
if ((len & 2) != 0) {
|
||||
if (@bitCast(u16, a[b_ptr..len][0..@sizeOf(u16)].*) != @bitCast(u16, b.ptr[b_ptr..len][0..@sizeOf(u16)].*))
|
||||
if (@bitCast(u16, a[0..@sizeOf(u16)].*) != @bitCast(u16, b[0..@sizeOf(u16)].*))
|
||||
return false;
|
||||
|
||||
b_ptr += @sizeOf(u16);
|
||||
b += @sizeOf(u16);
|
||||
|
||||
if (b_ptr == b.len) return true;
|
||||
if (b == end) return true;
|
||||
|
||||
a += @sizeOf(u16);
|
||||
}
|
||||
|
||||
if (((len & 1) != 0) and a[b_ptr] != b[b_ptr]) return false;
|
||||
if (((len & 1) != 0) and a[0] != b[0]) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub inline fn append(allocator: std.mem.Allocator, self: string, other: string) ![]u8 {
|
||||
return std.fmt.allocPrint(allocator, "{s}{s}", .{ self, other });
|
||||
var buf = try allocator.alloc(u8, self.len + other.len);
|
||||
if (self.len > 0)
|
||||
@memcpy(buf.ptr, self.ptr, self.len);
|
||||
if (other.len > 0)
|
||||
@memcpy(buf.ptr + self.len, other.ptr, other.len);
|
||||
return buf;
|
||||
}
|
||||
|
||||
pub inline fn joinBuf(out: []u8, parts: anytype, comptime parts_len: usize) []u8 {
|
||||
@@ -798,7 +828,7 @@ pub inline fn joinBuf(out: []u8, parts: anytype, comptime parts_len: usize) []u8
|
||||
}
|
||||
|
||||
pub fn index(self: string, str: string) i32 {
|
||||
if (std.mem.indexOf(u8, self, str)) |i| {
|
||||
if (strings.indexOf(self, str)) |i| {
|
||||
return @intCast(i32, i);
|
||||
} else {
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user