Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(codec): avoid re-construct when concat bytes #375

Merged
merged 1 commit into from
Jul 28, 2022

Conversation

homura
Copy link
Collaborator

@homura homura commented Jul 28, 2022

Resolve #374, the concat is used by every molecule layout and the current implementation is low performance.

This PR refactors concat via re-alloc a new Uint8Array and the benchmark has an improvement of about 100x

concat#re-construct x 21.36 ops/sec ±1.44% (40 runs sampled)
concat#re-alloc x 2,525 ops/sec ±1.73% (90 runs sampled)
benchmark.js
import Benchmark from "benchmark";
import { concat, concatViaReconstruct } from "@ckb-lumos/codec/lib/bytes";
import { randomBytes } from "crypto";

// export function concatViaReconstruct(...bytesLikes: BytesLike[]): Uint8Array {
//   return Uint8Array.from(
//     bytesLikes.flatMap((bytes) => Array.from(bytify(bytes)))
//   );
// }
//
// export function concat(...bytesLikes: BytesLike[]): Uint8Array {
//   const unmerged = bytesLikes.map(bytify);
//   const totalSize = unmerged.reduce((size, item) => size + item.length, 0);
//
//   const merged = new Uint8Array(totalSize);
//
//   let offset = 0;
//   unmerged.forEach((item) => {
//     merged.set(item, offset);
//     offset += item.length;
//   });
//
//   return merged;
// }

const bytesArr = Array.from({ length: 1000 }).map(() =>
  randomBytes(Math.ceil(1000 * Math.random()))
);

const suite = new Benchmark.Suite();

suite
  .add("concat#re-construct", () => {
    return concatViaReconstruct(...bytesArr);
  })
  .add("concat#re-alloc", () => {
    return concat(...bytesArr);
  })
  .on("cycle", function (event: any) {
    console.log(String(event.target));
  })
  .run();

@vercel
Copy link

vercel bot commented Jul 28, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
lumos-website ✅ Ready (Inspect) Visit Preview Jul 28, 2022 at 2:59AM (UTC)

@codecov
Copy link

codecov bot commented Jul 28, 2022

Codecov Report

Merging #375 (9c4cbf0) into develop (d91a96f) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff            @@
##           develop     #375   +/-   ##
========================================
  Coverage    82.24%   82.25%           
========================================
  Files           81       81           
  Lines        17659    17668    +9     
  Branches      1695     1696    +1     
========================================
+ Hits         14524    14533    +9     
  Misses        3112     3112           
  Partials        23       23           
Impacted Files Coverage Δ
packages/codec/src/bytes.ts 98.70% <100.00%> (+0.17%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d91a96f...9c4cbf0. Read the comment docs.

Copy link
Contributor

@zhangyouxin zhangyouxin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@homura homura merged commit 1669bf5 into ckb-js:develop Jul 28, 2022
@homura homura deleted the bytes-concat-perf branch July 28, 2022 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Potential performance issue of codec
2 participants