Skip to content

Commit

Permalink
perf: Faster base64FromBytes & bytesFromBase64 on Node.JS (#649)
Browse files Browse the repository at this point in the history
* ⚡️ Improve base64FromBytes & bytesFromBase64 perf on Node.JS

* ✅ Return Uint8Array instead of Buffer subclass
  • Loading branch information
coyotte508 authored Aug 6, 2022
1 parent 19526af commit 82ab341
Show file tree
Hide file tree
Showing 20 changed files with 344 additions and 278 deletions.
32 changes: 18 additions & 14 deletions integration/bytes-as-base64/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,29 @@ var globalThis: any = (() => {
throw 'Unable to locate global object';
})();

const atob: (b64: string) => string =
globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
function bytesFromBase64(b64: string): Uint8Array {
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
if (globalThis.Buffer) {
return Uint8Array.from(globalThis.Buffer.from(b64, 'base64'));
} else {
const bin = globalThis.atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
}
return arr;
}
return arr;
}

const btoa: (bin: string) => string =
globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
function base64FromBytes(arr: Uint8Array): string {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return btoa(bin.join(''));
if (globalThis.Buffer) {
return globalThis.Buffer.from(arr).toString('base64');
} else {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return globalThis.btoa(bin.join(''));
}
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
Expand Down
32 changes: 18 additions & 14 deletions integration/bytes-node/google/protobuf/wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,25 +547,29 @@ var globalThis: any = (() => {
throw 'Unable to locate global object';
})();

const atob: (b64: string) => string =
globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
function bytesFromBase64(b64: string): Uint8Array {
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
if (globalThis.Buffer) {
return Uint8Array.from(globalThis.Buffer.from(b64, 'base64'));
} else {
const bin = globalThis.atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
}
return arr;
}
return arr;
}

const btoa: (bin: string) => string =
globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
function base64FromBytes(arr: Uint8Array): string {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return btoa(bin.join(''));
if (globalThis.Buffer) {
return globalThis.Buffer.from(arr).toString('base64');
} else {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return globalThis.btoa(bin.join(''));
}
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
Expand Down
32 changes: 18 additions & 14 deletions integration/bytes-node/point.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,25 +79,29 @@ var globalThis: any = (() => {
throw 'Unable to locate global object';
})();

const atob: (b64: string) => string =
globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
function bytesFromBase64(b64: string): Uint8Array {
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
if (globalThis.Buffer) {
return Uint8Array.from(globalThis.Buffer.from(b64, 'base64'));
} else {
const bin = globalThis.atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
}
return arr;
}
return arr;
}

const btoa: (bin: string) => string =
globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
function base64FromBytes(arr: Uint8Array): string {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return btoa(bin.join(''));
if (globalThis.Buffer) {
return globalThis.Buffer.from(arr).toString('base64');
} else {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return globalThis.btoa(bin.join(''));
}
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
Expand Down
32 changes: 18 additions & 14 deletions integration/grpc-js/google/protobuf/wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,25 +547,29 @@ var globalThis: any = (() => {
throw 'Unable to locate global object';
})();

const atob: (b64: string) => string =
globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
function bytesFromBase64(b64: string): Uint8Array {
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
if (globalThis.Buffer) {
return Uint8Array.from(globalThis.Buffer.from(b64, 'base64'));
} else {
const bin = globalThis.atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
}
return arr;
}
return arr;
}

const btoa: (bin: string) => string =
globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
function base64FromBytes(arr: Uint8Array): string {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return btoa(bin.join(''));
if (globalThis.Buffer) {
return globalThis.Buffer.from(arr).toString('base64');
} else {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return globalThis.btoa(bin.join(''));
}
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
Expand Down
32 changes: 18 additions & 14 deletions integration/nice-grpc/google/protobuf/wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,25 +547,29 @@ var globalThis: any = (() => {
throw 'Unable to locate global object';
})();

const atob: (b64: string) => string =
globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
function bytesFromBase64(b64: string): Uint8Array {
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
if (globalThis.Buffer) {
return Uint8Array.from(globalThis.Buffer.from(b64, 'base64'));
} else {
const bin = globalThis.atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
}
return arr;
}
return arr;
}

const btoa: (bin: string) => string =
globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
function base64FromBytes(arr: Uint8Array): string {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return btoa(bin.join(''));
if (globalThis.Buffer) {
return globalThis.Buffer.from(arr).toString('base64');
} else {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return globalThis.btoa(bin.join(''));
}
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
Expand Down
32 changes: 18 additions & 14 deletions integration/oneof-properties/oneof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,25 +289,29 @@ var globalThis: any = (() => {
throw 'Unable to locate global object';
})();

const atob: (b64: string) => string =
globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
function bytesFromBase64(b64: string): Uint8Array {
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
if (globalThis.Buffer) {
return Uint8Array.from(globalThis.Buffer.from(b64, 'base64'));
} else {
const bin = globalThis.atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
}
return arr;
}
return arr;
}

const btoa: (bin: string) => string =
globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
function base64FromBytes(arr: Uint8Array): string {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return btoa(bin.join(''));
if (globalThis.Buffer) {
return globalThis.Buffer.from(arr).toString('base64');
} else {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return globalThis.btoa(bin.join(''));
}
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
Expand Down
32 changes: 18 additions & 14 deletions integration/oneof-unions/oneof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,25 +397,29 @@ var globalThis: any = (() => {
throw 'Unable to locate global object';
})();

const atob: (b64: string) => string =
globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
function bytesFromBase64(b64: string): Uint8Array {
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
if (globalThis.Buffer) {
return Uint8Array.from(globalThis.Buffer.from(b64, 'base64'));
} else {
const bin = globalThis.atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
}
return arr;
}
return arr;
}

const btoa: (bin: string) => string =
globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
function base64FromBytes(arr: Uint8Array): string {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return btoa(bin.join(''));
if (globalThis.Buffer) {
return globalThis.Buffer.from(arr).toString('base64');
} else {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return globalThis.btoa(bin.join(''));
}
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
Expand Down
32 changes: 18 additions & 14 deletions integration/simple-long-string/google/protobuf/wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,25 +547,29 @@ var globalThis: any = (() => {
throw 'Unable to locate global object';
})();

const atob: (b64: string) => string =
globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
function bytesFromBase64(b64: string): Uint8Array {
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
if (globalThis.Buffer) {
return Uint8Array.from(globalThis.Buffer.from(b64, 'base64'));
} else {
const bin = globalThis.atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
}
return arr;
}
return arr;
}

const btoa: (bin: string) => string =
globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
function base64FromBytes(arr: Uint8Array): string {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return btoa(bin.join(''));
if (globalThis.Buffer) {
return globalThis.Buffer.from(arr).toString('base64');
} else {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return globalThis.btoa(bin.join(''));
}
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
Expand Down
32 changes: 18 additions & 14 deletions integration/simple-long/google/protobuf/wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,25 +547,29 @@ var globalThis: any = (() => {
throw 'Unable to locate global object';
})();

const atob: (b64: string) => string =
globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
function bytesFromBase64(b64: string): Uint8Array {
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
if (globalThis.Buffer) {
return Uint8Array.from(globalThis.Buffer.from(b64, 'base64'));
} else {
const bin = globalThis.atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
arr[i] = bin.charCodeAt(i);
}
return arr;
}
return arr;
}

const btoa: (bin: string) => string =
globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
function base64FromBytes(arr: Uint8Array): string {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return btoa(bin.join(''));
if (globalThis.Buffer) {
return globalThis.Buffer.from(arr).toString('base64');
} else {
const bin: string[] = [];
arr.forEach((byte) => {
bin.push(String.fromCharCode(byte));
});
return globalThis.btoa(bin.join(''));
}
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
Expand Down
Loading

0 comments on commit 82ab341

Please sign in to comment.