Piscina FixedQueue 실험: 더 빠르지 않았어요
단일 Worker Thread에서 대량 작업을 제출한 실험에서는 FixedQueue의 중앙 실행 시간이 기본 대기열보다 길었어요. README의 최대 여섯 배 단축 주장은 이 조건에서 확인되지 않았고 대기열 선택은 실제 작업 규모와 실행 조건을 먼저 측정한 뒤 결정해야 해요.
2026-10-24 기준, 이 사이트의 단일 Worker Thread 실험에서 FixedQueue 중앙 실행 시간은 5871.809709ms로 기본 대기열의 5695.225011ms보다 길었어요. 대량 작업을 한꺼번에 넣는 상황에서도 이 조건에서는 FixedQueue가 더 짧은 처리 시간을 보이지 않았어요.
README 주장의 범위
Piscina README는 대규모 대기 작업에서 FixedQueue가 기본 대기열보다 실행 시간을 최대 여섯 배 줄인다고 제시해요. 이 숫자는 이 사이트의 측정값이 아니라 원문 주장이고 여기서도 그 범위를 넘겨 해석하면 안 돼요. README 원문
원문 주장은 특정 구현과 부하 조건에서 얻은 결과일 수 있어요.
그래서 이번 실험은 ‘FixedQueue가 언제나 유리한가’가 아니라, 단일 Worker Thread에 같은 결정적 작업을 대량 제출할 때 같은 방향이 나오는지를 확인하는 가설로 좁혔어요.
README가 말한 최대 여섯 배와 이번 결과의 시간을 직접 같은 기준으로 놓을 수 없는 이유도 여기에 있어요. README 원문
실험 조건과 측정 방법
이 사이트의 격리 환경에서 대기열 두 종류를 각각 5회 실행했어요. 환경은 aarch64, Neoverse-N1 x2와 CPUQuota 150%, 메모리 2048MB, Ubuntu 24.04.4 LTS, Node.js 24.21.0이었어요.
원문과 달리 단일 Worker Thread를 사용했고 작업은 단순 정수 증가였어요.
두 대기열에 같은 수의 결정적 작업을 제출한 뒤 모든 결과를 기다렸어요.
풀 생성과 워커 초기화는 측정 구간에서 제외했고 각 대기열은 측정 전에 한 번 워밍업했어요.
측정 대상은 작업 제출부터 모든 결과를 받기까지의 경과 시간이에요.
결과 배열의 길이와 마지막 결과도 확인했기 때문에, 단순히 빠르게 끝난 것처럼 보이는 중간 실패를 정상 결과로 세지 않도록 했어요.
원시 실행값과 차트 선언은 원시 데이터(JSON)에서 확인할 수 있어요.
결과: 단일 워커의 대량 제출 시간
이 조건에서 FixedQueue의 중앙값은 기본 대기열보다 길었어요. 각 회차의 차이는 크지 않았지만 중앙값과 최소·최대 범위 모두 두 구현을 같은 조건에서 기록한 값이에요.
그림. 같은 입력을 5회 측정했어요. 막대는 중앙값, 아래 선은 최소–최대, 점은 회차별 값이에요. 두 범위는 겹치지만(기본 최댓값 5,961 ms > Fixed 최솟값 5,703 ms), 같은 회차끼리 비교하면 5회 모두 기본 쪽이 빨랐어요(1.00–1.05배). 환경: aarch64 · Neoverse-N1 x2, CPUQuota 150% · 2048MB · Node.js 24.21.0 · 원시 데이터(JSON)
표로 보기 · 5회 원자료
| 회차 | FixedQueue | 기본 대기열 |
|---|---|---|
| 1 | 5,887 | 5,817 |
| 2 | 5,978 | 5,961 |
| 3 | 5,743 | 5,619 |
| 4 | 5,872 | 5,616 |
| 5 | 5,703 | 5,695 |
| 중앙값 | 5,872 | 5,695 |
| 최소 | 5,703 | 5,616 |
| 최대 | 5,978 | 5,961 |
| 대기열 | 중앙값 | 최소 | 최대 |
|---|---|---|---|
| FixedQueue | 5871.809709ms | 5703.423997ms | 5978.08928ms |
| 기본 대기열 | 5695.225011ms | 5615.998694ms | 5960.895902ms |
실행 회차를 보면 FixedQueue는 5886.923306999999ms, 5978.08928ms, 5743.005073999999ms, 5871.809708999999ms, 5703.423997000002ms였어요. 기본 대기열은 5816.813745000003ms, 5960.895902ms, 5619.452682000003ms, 5615.998694000002ms, 5695.225011000002ms였어요. 이 수치는 이 사이트가 같은 환경에서 두 대기열을 직접 비교해 측정한 결과예요.
가설은 FixedQueue의 처리 시간이 더 짧다는 것이었지만 이 조건의 중앙값은 반대 방향이었어요.
따라서 이 결과만으로 README의 주장이 틀렸다고 단정할 수는 없어요.
원문의 조건과 이번 조건이 다르고 이번 측정은 단일 Worker Thread와 단순 정수 증가 작업에 한정됐기 때문이에요.
재현에 사용한 스크립트
아래 코드는 이 사이트의 실험에 사용한 스크립트예요.
FixedQueue와 기본 대기열을 같은 방식으로 워밍업한 뒤, 각각의 처리 시간을 기록해요.
코드는 재현 절차를 보여 주지만 여기서는 새로 실행하지 않았어요.
import { writeFile, rm } from 'node:fs/promises';
import { resolve } from 'node:path';
import { performance } from 'node:perf_hooks';
import { Piscina, FixedQueue } from 'piscina';
const workerPath = resolve(process.cwd(), 'piscina-benchmark-worker.mjs');
const taskCount = 100_000;
await writeFile(workerPath, 'export default (value) => value + 1;\n');
async function drain(taskQueue) {
const pool = new Piscina({ filename: workerPath, minThreads: 1, maxThreads: 1, ...(taskQueue ? { taskQueue } : {}) });
await pool.run(0);
const started = performance.now();
const tasks = Array.from({ length: taskCount }, (_, index) => pool.run(index));
const results = await Promise.all(tasks);
const elapsed = performance.now() - started;
if (results.length !== taskCount || results[taskCount - 1] !== taskCount) throw new Error('unexpected result');
await pool.destroy();
return elapsed;
}
try {
await drain(new FixedQueue());
await drain();
const fixedQueueMs = await drain(new FixedQueue());
const defaultQueueMs = await drain();
console.log(JSON.stringify({ fixedQueueMs, defaultQueueMs }));
} finally {
await rm(workerPath, { force: true });
}
선택 기준과 한계
이번 실험의 직접 비교는 대기열 구현을 바꾼 뒤에도 단일 워커와 단순 작업의 처리 시간이 자동으로 줄지 않는다는 근거예요. 특히 원문과 다른 환경·작업·워커 수에서는 README의 방향을 배포 전 성능 보증으로 바꾸면 안 돼요.
대량 제출을 처리하는 서비스라면, FixedQueue 도입 전과 후를 같은 작업 수와 같은 워커 구성으로 측정하는 편이 안전해요.
이 사이트의 조건과 비슷한 단일 Worker Thread·단순 정수 증가 작업이라면 기본 대기열을 기준선으로 두는 판단이 맞아요.
반대로 원문이 전제한 대규모 대기 작업이나 다른 워커 구성이라면 이 결과를 그대로 일반화하지 말고 그 환경에서 다시 측정해야 해요.
이 글의 결과는 aarch64, Neoverse-N1 x2, CPUQuota 150%, 2048MB, Ubuntu 24.04.4 LTS, Node.js 24.21.0에서 얻었어요. 실행 횟수와 작업 내용, 워커 수를 바꾸면 결과도 달라질 수 있어요. 원시 데이터(JSON)에는 이 글의 범위를 다시 확인할 수 있는 실행값이 남아 있어요.
관련 글
Pino와 Console JSON 로그, 이 조건에서는 Console이 빨랐어요
격리 환경에서 구조화 로그를 기록하자 Pino 중앙값은 46.348412ms, Console 기반 JSON 로그는 24.277994ms였어요. 출력 소비 비용을 뺀 이 비교에서는 Pino가 더 빨라야 한다는 가설과 반대 방향이었고, 로거 선택 전 워크로드를 분리해 재야 한다는 결과예요.
대규모 저장소의 Git 운영 기준
대규모 저장소에서 Git을 계속 빠르게 쓰려면 작업트리, 내려받는 객체, 저장소 유지보수를 분리해 관리해야 해요. sparse-checkout·partial clone·maintenance를 어떤 병목에 쓸지와 피해야 할 조합을 공식 문서 기준으로 정리해요.
OpenMAIC란? 수업 도구 선택 기준
OpenMAIC는 주제나 문서를 다중 AI 에이전트가 참여하는 상호작용 수업으로 바꾸는 오픈소스 플랫폼이에요. 기능 목록보다는 단순 자료 전달이 아니라 토론·퀴즈·화이트보드가 필요한 수업 흐름에 맞는지 먼저 가르는 일이 중요해요.
공개 자료를 바탕으로 AI가 쓰고, 발행 전에 수치와 주장을 원문과 대조합니다.