Skip to content

perf: fix O(n²) arrayBufferToBase64 + efficiency audit report#1

Closed
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1771416356-perf-fix-base64
Closed

perf: fix O(n²) arrayBufferToBase64 + efficiency audit report#1
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1771416356-perf-fix-base64

Conversation

@devin-ai-integration

Copy link
Copy Markdown

perf: fix O(n²) string concatenation in arrayBufferToBase64

Summary

Replaces the byte-by-byte string concatenation in arrayBufferToBase64 (backend/utils/base64.js) with a chunked approach. The old code appended one character at a time via binary += String.fromCharCode(bytes[i]), which is O(n²) because JS strings are immutable and each += allocates a new string. For a 2 MB image buffer, this means ~2 million intermediate string copies.

The new implementation processes the buffer in 8 KB chunks using String.fromCharCode.apply(null, slice), collects the chunks in an array, and joins once at the end — making it O(n).

This function is called on every image generation request, so the improvement matters at scale.

Efficiency audit (other spots identified but not fixed)

During the audit, these additional inefficiencies were noted for future work:

Location Issue
backend/utils/response.js (lines 14–18, 30–34, 46–50, 78–82) Every response iterates all headers to build a log string via += concatenation — runs 3–4× per request
backend/index.js (lines 40–49) Logs every request header via += loop on every incoming request
backend/utils/cors.js parseAllowedOrigins Re-parses ALLOWED_ORIGINS env string on every request; result is constant per worker lifetime
backend/services/generation.js isPremiumModel Linear Array.includes() on a static list; a Set would give O(1) lookup
backend/auth.js resolvePBKDF2Digest (line 158) Allocates new Set(["sha256","sha384","sha512"]) on every call; could be a module-level constant

Review & Testing Checklist for Human

  • Verify identical output: run the old and new arrayBufferToBase64 against a sample ArrayBuffer and confirm the base64 strings match — there are no unit tests covering this function
  • End-to-end image generation: trigger an image generation request and confirm the returned base64 image renders correctly in the browser
  • Stack safety of String.fromCharCode.apply: the 8192 chunk size is well within safe apply argument limits for V8/Cloudflare Workers, but confirm this holds for the target runtime

Notes

…ayBufferToBase64

The previous implementation built a binary string by appending one character
at a time (binary += String.fromCharCode(bytes[i])), which is O(n²) for
large buffers because JavaScript strings are immutable and each += creates
a new string copy.

The new implementation processes the buffer in 8 KB chunks using
String.fromCharCode.apply() and joins them once at the end, reducing
the operation to O(n) and significantly improving performance for
image payloads (which can be up to 2 MB).

Co-Authored-By: 396217818@qq.com <396217818@qq.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying text2image-frontend-git with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5e3710d
Status: ✅  Deploy successful!
Preview URL: https://99404684.text2image-frontend-git.pages.dev
Branch Preview URL: https://devin-1771416356-perf-fix-ba.text2image-frontend-git.pages.dev

View logs

@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@devin-ai-integration

Copy link
Copy Markdown
Author

Closing due to inactivity for more than 7 days. Configure here.

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.

1 participant