Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@
## 2026-07-13 - Array.from mapping optimization
**Learning:** Using `Array.from({ length: N }).map(...)` creates an intermediate array of `undefined` values which requires memory allocation and garbage collection, adding O(N) unnecessary overhead in frequently re-rendered UI components.
**Action:** Use `Array.from({ length: N }, (_, index) => ...)` to map elements directly during array creation, avoiding intermediate allocations.

## 2026-08-10 - Array density check optimization
**Learning:** Using `Array.from().every()` to check for array density creates O(N) intermediate array allocations which add unnecessary garbage collection overhead on the critical path.
**Action:** Use a standard for-loop with an early return for an O(1) memory and faster check.
20 changes: 20 additions & 0 deletions apps/desktop/src/features/score/scoreStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,24 @@ describe("scoreStorage bridge resolution", () => {
BRIDGE_UNAVAILABLE_MESSAGE
);
});
it("uses the fallback loop for array density checking", async () => {
const tauriWindow = window as TauriWindow;
tauriWindow.__TAURI_INVOKE__ = vi.fn().mockResolvedValue([1, 2, 3]);

const result = await readScorePdf("project-1", "score-1");
expect(result).toBeInstanceOf(Uint8Array);
expect(result.length).toBe(3);
expect(result[0]).toBe(1);
expect(result[1]).toBe(2);
expect(result[2]).toBe(3);
});

it("fails array density check if non-number elements are present", async () => {
const tauriWindow = window as TauriWindow;
tauriWindow.__TAURI_INVOKE__ = vi.fn().mockResolvedValue([1, "two", 3]);

await expect(readScorePdf("project-1", "score-1")).rejects.toThrow(
"Invalid score bridge response"
);
});
});
15 changes: 13 additions & 2 deletions apps/desktop/src/features/score/scoreStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,19 @@ export async function readScorePdf(projectId: string, scoreId: string): Promise<
if (response instanceof ArrayBuffer) {
return new Uint8Array(response);
}
if (Array.isArray(response) && response.every((byte) => typeof byte === "number")) {
return Uint8Array.from(response as number[]);
if (Array.isArray(response)) {
// 성능 최적화: O(N) 콜백 호출 오버헤드를 줄이기 위해 for 루프 사용
let isNumberArray = true;
for (let i = 0; i < response.length; i++) {
if (typeof response[i] !== "number") {
isNumberArray = false;
break;
}
}

if (isNumberArray) {
return Uint8Array.from(response as number[]);
}
}

throw new Error(INVALID_RESPONSE_MESSAGE);
Expand Down
Loading