Skip to content

Commit

Permalink
performance improvement to byte array concatenation
Browse files Browse the repository at this point in the history
  • Loading branch information
j50n committed Mar 11, 2022
1 parent 8de2817 commit 6e9efa1
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
4 changes: 4 additions & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release Notes

## 0.19.2

- Performance improvement to byte array concatenation.

## 0.19.1

- Fix line split to correctly remove trailing carriage returns on lines and to
Expand Down
24 changes: 21 additions & 3 deletions runners/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,34 @@ export async function* readerToBytesUnbuffered(
}
}

/**
* Concatenate arrays together, returning a single array containing the result.
*
* Note that this may return the original source data rather than a copy in some
* circumstances.
*
* @param arrays The arrays to concatenate together.
* @returns The result of the concatenation.
*/
export function concat(arrays: Uint8Array[]): Uint8Array {
if (!arrays.length) return new Uint8Array(0);

/*
* In many cases, we are dealing with data that actually only contains a single array of bytes
* and does not actually need to be concatenated. In this case, we just return the first buffer
* from the array (it is the only buffer) and skip the processing, saving a redundant memcpy.
*/
if (arrays.length === 1) {
return arrays[0];
}

const totalLength = arrays.reduce((acc, value) => acc + value.length, 0);
const result = new Uint8Array(totalLength);

let length = 0;
let pos = 0;
for (const array of arrays) {
result.set(array, length);
length += array.length;
result.set(array, pos);
pos += array.length;
}

return result;
Expand Down
14 changes: 14 additions & 0 deletions tests/piped.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
import * as proc from "../mod.ts";

Deno.test({
name: "Output printed to stderr does not end up in the output.",
async fn() {
assertEquals(
await proc.runSa({
cmd: ["bash", "-c", "echo 'a\nb\n' && echo 'printed to stderr' >&2"],
}),
["a", "b"],
);
},
});

0 comments on commit 6e9efa1

Please sign in to comment.