mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Faster Buffer.toString("ascii")
This commit is contained in:
@@ -796,15 +796,42 @@ pub const Encoder = struct {
|
||||
switch (comptime encoding) {
|
||||
.ascii => {
|
||||
var to = allocator.alloc(u8, len) catch return ZigString.init("Out of memory").toErrorInstance(global);
|
||||
var complete = to;
|
||||
var remain = input;
|
||||
|
||||
@memcpy(to.ptr, input_ptr, to.len);
|
||||
if (comptime bun.Environment.enableSIMD) {
|
||||
const vector_size = 16;
|
||||
// https://zig.godbolt.org/z/qezsY8T3W
|
||||
var remain_in_u64 = remain[0 .. remain.len - (remain.len % vector_size)];
|
||||
var to_in_u64 = to[0 .. to.len - (to.len % vector_size)];
|
||||
var remain_as_u64 = std.mem.bytesAsSlice(u64, remain_in_u64);
|
||||
var to_as_u64 = std.mem.bytesAsSlice(u64, to_in_u64);
|
||||
const inner_vector_size = vector_size / 8;
|
||||
const end_vector_len = @min(remain_as_u64.len, to_as_u64.len);
|
||||
remain_as_u64 = remain_as_u64[0..end_vector_len];
|
||||
to_as_u64 = to_as_u64[0..end_vector_len];
|
||||
const end_ptr = remain_as_u64.ptr + remain_as_u64.len;
|
||||
// using the pointer instead of the length is super important for the codegen
|
||||
while (end_ptr != remain_as_u64.ptr) {
|
||||
const buf = @as(@Vector(inner_vector_size, u64), remain_as_u64[0..inner_vector_size].*);
|
||||
const mask = @splat(inner_vector_size, @as(u64, 0x7f7f7f7f7f7f7f7f));
|
||||
to_as_u64[0..inner_vector_size].* = buf & mask;
|
||||
|
||||
// Hoping this gets auto vectorized
|
||||
for (to[0..to.len]) |c, i| {
|
||||
to[i] = @as(u8, @truncate(u7, c));
|
||||
remain_as_u64 = remain_as_u64[inner_vector_size..];
|
||||
to_as_u64 = to_as_u64[inner_vector_size..];
|
||||
}
|
||||
remain = remain[remain_in_u64.len..];
|
||||
to = to[to_in_u64.len..];
|
||||
}
|
||||
|
||||
return ZigString.init(to).toExternalValue(global);
|
||||
const end_ptr = to.ptr + to.len;
|
||||
while (to.ptr != end_ptr) {
|
||||
to[0] = @as(u8, @truncate(u7, remain[0]));
|
||||
to = to[1..];
|
||||
remain = remain[1..];
|
||||
}
|
||||
|
||||
return ZigString.init(complete).toExternalValue(global);
|
||||
},
|
||||
.latin1 => {
|
||||
var to = allocator.alloc(u8, len) catch return ZigString.init("Out of memory").toErrorInstance(global);
|
||||
@@ -919,7 +946,7 @@ pub const Encoder = struct {
|
||||
if (slice.len == 0)
|
||||
return 0;
|
||||
|
||||
if (slice.len > 1 and strings.eqlComptime(slice[slice.len - 2 ..][0..2], "==")) {
|
||||
if (strings.endsWithComptime(slice, "==")) {
|
||||
slice = slice[0 .. slice.len - 2];
|
||||
} else if (slice[slice.len - 1] == '=') {
|
||||
slice = slice[0 .. slice.len - 1];
|
||||
@@ -1094,7 +1121,7 @@ pub const Encoder = struct {
|
||||
if (slice.len == 0)
|
||||
return &[_]u8{};
|
||||
|
||||
if (slice.len > 1 and strings.eqlComptime(slice[slice.len - 2 ..][0..2], "==")) {
|
||||
if (strings.endsWithComptime(slice, "==")) {
|
||||
slice = slice[0 .. slice.len - 2];
|
||||
} else if (slice[slice.len - 1] == '=') {
|
||||
slice = slice[0 .. slice.len - 1];
|
||||
|
||||
Reference in New Issue
Block a user