aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-07-01 20:02:50 -0700
committerGravatar GitHub <noreply@github.com> 2023-07-01 20:02:50 -0700
commit6cae6ebafeac4ec2698dc746838b91b2f079f65f (patch)
tree19b69c16306f78ea829c26eaaf9d4c8f6e1c54b7 /src
parenta2cca6e292d8e077306ba3b1b0c381a6441bbd61 (diff)
downloadbun-6cae6ebafeac4ec2698dc746838b91b2f079f65f.tar.gz
bun-6cae6ebafeac4ec2698dc746838b91b2f079f65f.tar.zst
bun-6cae6ebafeac4ec2698dc746838b91b2f079f65f.zip
Make `buffer.toString("base64")` 4x faster (#3486)
* Add libbase64 * Add bench * Update licensing.md --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/base64/base64.zig20
-rw-r--r--src/bun.js/node/types.zig4
m---------src/deps/base640
3 files changed, 21 insertions, 3 deletions
diff --git a/src/base64/base64.zig b/src/base64/base64.zig
index bddc44564..8768b9c7b 100644
--- a/src/base64/base64.zig
+++ b/src/base64/base64.zig
@@ -5,6 +5,22 @@ pub const DecodeResult = struct {
fail: bool = false,
};
+pub const LibBase64 = struct {
+ pub const State = extern struct {
+ eof: c_int,
+ bytes: c_int,
+ flags: c_int,
+ carry: u8,
+ };
+ pub extern fn base64_encode(src: [*]const u8, srclen: usize, out: [*]u8, outlen: *usize, flags: c_int) void;
+ pub extern fn base64_stream_encode_init(state: *State, flags: c_int) void;
+ pub extern fn base64_stream_encode(state: *State, src: [*]const u8, srclen: usize, out: [*]u8, outlen: *usize) void;
+ pub extern fn base64_stream_encode_final(state: *State, out: [*]u8, outlen: *usize) void;
+ pub extern fn base64_decode(src: [*]const u8, srclen: usize, out: [*]u8, outlen: *usize, flags: c_int) c_int;
+ pub extern fn base64_stream_decode_init(state: *State, flags: c_int) void;
+ pub extern fn base64_stream_decode(state: *State, src: [*]const u8, srclen: usize, out: [*]u8, outlen: *usize) c_int;
+};
+
const mixed_decoder = brk: {
var decoder = zig_base64.standard.decoderWithIgnore("\xff \t\r\n" ++ [_]u8{
std.ascii.control_code.vt,
@@ -30,7 +46,9 @@ pub fn decode(destination: []u8, source: []const u8) DecodeResult {
}
pub fn encode(destination: []u8, source: []const u8) usize {
- return zig_base64.standard.Encoder.encode(destination, source).len;
+ var outlen: usize = destination.len;
+ LibBase64.base64_encode(source.ptr, source.len, destination.ptr, &outlen, 0);
+ return outlen;
}
pub fn decodeLenUpperBound(len: usize) usize {
diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig
index b01eca8e0..96d04636e 100644
--- a/src/bun.js/node/types.zig
+++ b/src/bun.js/node/types.zig
@@ -524,8 +524,8 @@ pub const Encoding = enum(u8) {
switch (encoding) {
.base64 => {
var base64: [std.base64.standard.Encoder.calcSize(size)]u8 = undefined;
- const result = JSC.ZigString.init(std.base64.standard.Encoder.encode(&base64, input)).toValueGC(globalThis);
- return result;
+ const len = bun.base64.encode(&base64, input);
+ return JSC.ZigString.init(base64[0..len]).toValueGC(globalThis);
},
.base64url => {
var buf: [std.base64.url_safe.Encoder.calcSize(size) + "data:;base64,".len]u8 = undefined;
diff --git a/src/deps/base64 b/src/deps/base64
new file mode 160000
+Subproject e77bd70bdd860c52c561568cffb251d88bba064