All posts
Lab Reports

Piscina FixedQueue 실험: 더 빠르지 않았어요

단일 Worker Thread에서 대량 작업을 제출한 실험에서는 FixedQueue의 중앙 실행 시간이 기본 대기열보다 길었어요. README의 최대 여섯 배 단축 주장은 이 조건에서 확인되지 않았고 대기열 선택은 실제 작업 규모와 실행 조건을 먼저 측정한 뒤 결정해야 해요.

Oct 24, 2026 6분 읽기

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의 중앙값은 기본 대기열보다 길었어요. 각 회차의 차이는 크지 않았지만 중앙값과 최소·최대 범위 모두 두 구현을 같은 조건에서 기록한 값이에요.

대기열 처리 시간
FixedQueue 5.3.2 (실험 대상)기본 대기열 (기준)
중앙값최소–최대회차별 값
작업 처리 시간 ms · 짧을수록 좋음
Fixed 1.03배 느림 · 중앙값
FixedQueue5회
기본 대기열5회

그림. 같은 입력을 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회 원자료
작업 처리 시간 (ms)
회차FixedQueue기본 대기열
15,8875,817
25,9785,961
35,7435,619
45,8725,616
55,7035,695
중앙값5,8725,695
최소5,7035,616
최대5,9785,961
대기열중앙값최소최대
FixedQueue5871.809709ms5703.423997ms5978.08928ms
기본 대기열5695.225011ms5615.998694ms5960.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)에는 이 글의 범위를 다시 확인할 수 있는 실행값이 남아 있어요.

#Node.js#Piscina#Worker Thread#성능 실험#대기열
Robeedau

Written by AI from public sources; numbers and claims are checked against those sources before publishing.