Skip to content

성능 벤치마크

이 페이지는 TCPDF-Next를 세 가지 주요 PHP PDF 라이브러리인 TCPDF, DomPDF, mPDF와 비교한 실제 벤치마크 결과를 제공합니다. 모든 수치는 동일한 Docker 환경에서 동일한 입력 문서를 사용하여 측정되었으며, 워밍업 라운드를 제외한 20회 측정의 중앙값(median)을 보고합니다. TCPDF-Next가 가장 빠르지 않은 경우에도 정직하게 공개합니다.

테스트 환경

파라미터
CPUIntel Core i9-13900K (x86-64)
RAM64 GB DDR5 (Docker 제한 16 GB)
Docker4 CPUs, 16 GB RAM, Ubuntu bookworm
PHP8.5.3 (CLI, OPcache 활성화, JIT 활성화)
TCPDF-Next1.6.0
TCPDF-NextArtisan (Chrome)1.0.0
TCPDF6.10.1
DomPDFv3.1.4
mPDFv8.2.7
워밍업3회 (폐기)
측정20회 (중앙값 보고)
시간 측정hrtime(true) 나노초 정밀도 벽시계 시간

TIP

모든 벤치마크는 Docker 기반으로 자동화되어 있으며, 누구나 동일한 환경에서 재현할 수 있습니다. 아래 벤치마크 재현 섹션을 참고하십시오.

인터랙티브 비교 차트

▼ Lower is better
TCPDF-Next
0.63 ms
TCPDF
2.5 ms4.0x
DomPDF
4.07 ms6.5x
mPDF
7.13 ms11.3x

PHP 8.5.3 + OPcache + JIT · Docker 4 CPUs / 16 GB · i9-13900K · Median of 20 runs


생성 속도

각 시나리오는 워밍업 후 20회 실행되었습니다. 아래 표는 중앙값 생성 시간, 피크 메모리, 출력 파일 크기, TCPDF-Next 대비 상대 속도를 보여줍니다.

간단한 문서 (1페이지)

제목, 세 단락의 텍스트, 기본 서식(볼드, 이탤릭)으로 구성된 단일 A4 페이지입니다. 이미지나 테이블은 포함되지 않습니다.

라이브러리시간 (ms)피크 메모리 (MB)파일 크기 (KB)
TCPDF-Next0.6343
TCPDF2.50 (3.97x 느림)12 (3.0x)7 (2.3x)
DomPDF4.07 (6.46x 느림)12 (3.0x)2 (0.7x)
mPDF7.13 (11.32x 느림)16 (4.0x)28 (9.3x)

TCPDF-Next는 가장 간단한 시나리오에서 1ms 미만으로 완료됩니다. TCPDF보다 약 4배, DomPDF보다 약 6.5배, mPDF보다 약 11배 빠릅니다.

인보이스 (2페이지)

회사 로고, 고객 정보 테이블, 30행 품목 목록, 합계, 바닥글이 포함된 2페이지 인보이스입니다.

라이브러리시간 (ms)피크 메모리 (MB)파일 크기 (KB)
TCPDF1.15169
TCPDF-Next1.641652
DomPDF19.09 (11.64x 느림*)164
mPDF21.66 (13.21x 느림*)1830

*TCPDF-Next 대비 상대 속도입니다.

정직한 참고

인보이스 시나리오에서는 레거시 TCPDF가 TCPDF-Next보다 1.4배 빠릅니다 (1.15 ms vs 1.64 ms). TCPDF는 또한 더 작은 출력 파일을 생성합니다 (9 KB vs 52 KB). 이는 TCPDF의 오랜 기간 최적화된 레거시 테이블 레이아웃 엔진이 단순한 표 형식 콘텐츠에서 약간의 우위를 가지기 때문입니다. 그럼에도 불구하고 두 라이브러리 모두 2ms 미만으로 실무 환경에서 체감 차이는 거의 없습니다. DomPDF와 mPDF는 10배 이상 느립니다.

100페이지 보고서

혼합 콘텐츠(제목, 단락, 임베디드 이미지, 머리글/바닥글)로 구성된 대용량 보고서입니다.

라이브러리시간 (ms)피크 메모리 (MB)파일 크기 (KB)
TCPDF-Next32.391896
TCPDF102.47 (3.16x 느림)18101
mPDF1,044.05 (32.23x 느림)82 (4.6x)181
DomPDF2,705.55 (83.52x 느림)70 (3.9x)129

100페이지 시나리오는 TCPDF-Next의 성능 우위가 가장 극적으로 드러나는 구간입니다. 32.39 ms로 TCPDF보다 3.2배 빠르고, DomPDF보다 83.5배 빠릅니다. 메모리 사용량은 TCPDF와 동일하며, DomPDF와 mPDF보다 현저히 낮습니다.


HTML→PDF 변환

HTML 마크업(제목, 단락, 링크, 기본 스타일)을 PDF로 변환하는 시나리오입니다. 두 가지 접근 방식을 비교합니다: 각 라이브러리의 내장 HTML 파서와 TCPDF-NextArtisan의 Chrome 렌더링 엔진입니다.

내장 HTML 파서

각 라이브러리에 내장된 HTML 파싱 엔진을 사용한 결과입니다.

라이브러리시간 (ms)피크 메모리 (MB)파일 크기 (KB)
TCPDF-Next0.93747
TCPDF7.62 (8.19x 느림)7413
DomPDF16.09 (17.30x 느림)745
mPDF33.62 (36.15x 느림)7446

TCPDF-Next의 HTML 파싱 엔진은 1ms 미만의 성능을 제공합니다. TCPDF보다 8배, mPDF보다 36배 빠릅니다. 네 라이브러리 모두 피크 메모리가 74 MB로 유사합니다. 이는 HTML 파싱 인프라 자체의 오버헤드가 라이브러리 간 차이를 상쇄하기 때문입니다.

Chrome 렌더링 (TCPDF-NextArtisan)

TCPDF-NextArtisan은 Headless Chrome을 활용하여 HTML을 픽셀 퍼펙트 PDF로 변환합니다.

라이브러리시간 (ms)피크 메모리 (MB)파일 크기 (KB)
TCPDF-NextArtisan (Chrome)309.857437

Chrome 렌더링 지연 시간에 대한 설명

Artisan Chrome 렌더링의 309.85 ms는 내장 파서 대비 상당히 느리지만, 이는 의도적인 속도 vs 품질 트레이드오프입니다.

지연의 원인은 다음과 같습니다:

  • Chrome Page 라이프사이클 오버헤드 — 복수의 CDP(Chrome DevTools Protocol) 왕복 통신이 필요합니다
  • printToPDF 자체 소요 시간 — Chrome의 PDF 출력에 약 200~300 ms가 소요됩니다
  • PDF 파싱 + XObject 임포트 — Chrome이 생성한 PDF를 TCPDF-Next 문서로 가져오는 추가 오버헤드가 있습니다
  • BrowserPool keep-alive 사용 중 — 브라우저 풀링을 통해 콜드 스타트를 방지하고 있지만, CDP 통신 오버헤드는 남습니다

핵심 차이점: DomPDF와 mPDF는 CSS 지원에 제한이 있어 복잡한 레이아웃을 정확하게 렌더링하지 못하는 경우가 많습니다. 반면 Artisan은 Chrome의 완전한 렌더링 엔진을 사용하므로 Flexbox, Grid, 미디어 쿼리, 웹 폰트 등 모든 최신 CSS를 지원하며 픽셀 퍼펙트 출력을 보장합니다. 시각적 정확성이 중요한 문서에서는 Artisan이 최적의 선택입니다.


피크 메모리 사용량

각 시나리오에서 memory_get_peak_usage(true)로 측정한 피크 메모리(MB)입니다. 값이 낮을수록 효율적입니다.

시나리오TCPDF-NextTCPDFDomPDFmPDF
간단한 문서4 MB12 MB12 MB16 MB
인보이스16 MB16 MB16 MB18 MB
100페이지18 MB18 MB70 MB82 MB
HTML→PDF (내장 파서)74 MB74 MB74 MB74 MB

간단한 문서에서 TCPDF-Next는 TCPDF/DomPDF 대비 3분의 1, mPDF 대비 4분의 1의 메모리만 사용합니다. 100페이지 보고서에서는 DomPDF(70 MB)와 mPDF(82 MB)가 TCPDF-Next/TCPDF(18 MB)보다 약 4배의 메모리를 소비합니다.

HTML→PDF 시나리오에서는 네 라이브러리 모두 74 MB로 동일한 메모리를 사용합니다. 이는 HTML 파싱에 필요한 DOM 트리 구조의 오버헤드가 라이브러리 간 차이를 상쇄하기 때문입니다.


파일 크기

생성된 PDF 파일의 크기(KB)입니다. 값이 낮을수록 작습니다.

시나리오TCPDF-NextTCPDFDomPDFmPDF
간단한 문서3 KB7 KB2 KB28 KB
인보이스52 KB9 KB4 KB30 KB
100페이지96 KB101 KB129 KB181 KB
HTML→PDF (내장 파서)7 KB13 KB5 KB46 KB

파일 크기는 시나리오에 따라 결과가 다릅니다. DomPDF는 간단한 문서와 인보이스에서 가장 작은 파일을 생성합니다. 이는 DomPDF가 최소한의 메타데이터와 간소화된 PDF 구조를 사용하기 때문입니다. 반면 대용량 문서(100페이지)에서는 TCPDF-Next가 가장 작은 파일을 생성하며, 이는 PDF 2.0의 바이너리 크로스 레퍼런스 스트림과 객체 스트림 압축 덕분입니다.


처리량 (Throughput)

간단한 1페이지 문서를 기준으로 초당/분당 생성 가능한 PDF 수를 측정합니다. 지속적인 부하 조건에서 각 라이브러리가 처리할 수 있는 문서 수를 나타냅니다.

초당 처리량

모드TCPDF-NextTCPDFDomPDFmPDF
싱글 스레드2,6841,244260133
4 워커9,4344,431939484

분당 처리량

모드TCPDF-NextTCPDFDomPDFmPDF
싱글 스레드161,01474,62615,5887,994
4 워커566,024265,83256,33429,044

4 워커 병렬 처리 시 TCPDF-Next는 초당 약 9,434건, 분당 약 566,024건의 PDF를 생성할 수 있습니다. 이는 TCPDF 대비 2.1배, DomPDF 대비 10배, mPDF 대비 약 19.5배의 처리량입니다. 대량 PDF 생성이 필요한 엔터프라이즈 환경(인보이스 발행, 보고서 생성, 명세서 출력)에서 이러한 처리량 차이는 인프라 비용 절감으로 직결됩니다.


디지털 서명 오버헤드 (PAdES)

TCPDF-Next는 PAdES(PDF Advanced Electronic Signatures) 표준을 지원하는 유일한 PHP PDF 라이브러리입니다. 아래는 10페이지 문서에 각 PAdES 수준의 서명을 적용할 때 추가되는 오버헤드입니다.

서명 수준추가 시간 (ms)추가 파일 크기 (KB)설명
PAdES B-B+15+5~8기본 서명 (CMS 서명 내장)
PAdES B-T+120*+8~12신뢰할 수 있는 타임스탬프 추가
PAdES B-LT+250*+15~50장기 검증 데이터 내장 (인증서 체인 + OCSP/CRL)
PAdES B-LTA+350*+20~60아카이브 타임스탬프 추가 (장기 보존용)

*TSA/OCSP 서버로의 네트워크 왕복 시간이 포함되어 있습니다. 실제 시간은 서버 지연 시간과 네트워크 환경에 따라 달라집니다.

TIP

PAdES B-B(기본 서명)는 약 15 ms와 5~8 KB만 추가하므로 대부분의 워크플로우에서 무시할 수 있는 수준입니다. B-T 이상의 수준은 타임스탬프 기관(TSA)과 OCSP 응답 서버 호출로 인한 네트워크 종속 지연이 발생합니다. PAdES B-B 수준은 네트워크 호출 없이 로컬에서 완료되므로 오프라인 환경에서도 사용할 수 있습니다.


PDF/A-4 아카이브 오버헤드

PDF/A-4는 장기 보존을 위한 국제 표준(ISO 19005-4)입니다. 표준 PDF 2.0 출력 대비 PDF/A-4 규정 준수 출력을 생성할 때의 추가 오버헤드입니다.

구성 요소추가 크기
sRGB ICC 프로파일+3 KB
XMP 메타데이터+2~5 KB
출력 인텐트+1~3 KB
전체 폰트 임베딩 (필요한 경우)폰트당 +50~500 KB
일반적 총 오버헤드+10~50 KB
생성 시간 오버헤드< 5%

TIP

PDF/A-4 모드에서도 폰트 서브셋팅이 기본적으로 적용됩니다. 오버헤드의 대부분은 ICC 프로파일과 확장된 XMP 메타데이터에서 발생하며, 실제 문서 크기에 비해 미미한 수준입니다.


TCPDF-Next가 빠른 이유

TCPDF-Next의 성능 우위는 의도적인 아키텍처 설계에 기반합니다.

  1. 최신 PDF 2.0 코어 — 렌더링 파이프라인을 PDF 2.0 전용으로 처음부터 구축하여, TCPDF를 느리게 만드는 레거시 호환성 레이어를 제거했습니다. 크로스 레퍼런스 스트림과 객체 스트림으로 I/O와 파일 크기를 동시에 줄입니다.

  2. JIT 친화적 코드 패스 — 핫 루프와 핵심 렌더링 메서드는 PHP 8의 JIT 컴파일러가 효율적인 머신 코드를 생성할 수 있도록 구조화되었습니다. 타이트하고 타입이 지정된 코드와 최소한의 분기로 JIT 최적화를 극대화합니다.

  3. 지연 리소스 로딩 — 폰트, 이미지, ICC 프로파일은 생성 시점이 아닌 최초 사용 시점에 로딩됩니다. 이미지를 포함하지 않는 문서에서는 이미지 처리 오버헤드가 전혀 발생하지 않습니다.

  4. 효율적인 메모리 레이아웃 — 페이지 객체는 압축되며, 공유 리소스(폰트, 색상 공간)를 참조 카운팅을 통해 재사용합니다. 이를 통해 긴 문서에서도 피크 메모리를 낮게 유지합니다.

  5. 최적화된 HTML 파서 — 레거시 TCPDF의 정규식 기반 HTML 파싱 대신, TCPDF-Next는 스트리밍 토큰 기반 파서를 사용하여 HTML을 단일 패스로 처리하며 최소한의 백트래킹으로 동작합니다.

  6. 병렬화 가능한 설계 — 상태 없는(stateless) 페이지 렌더링 아키텍처 덕분에 워크로드가 여러 워커에 걸쳐 선형적으로 확장됩니다. 4 워커 사용 시 거의 4배에 가까운 처리량 향상이 이를 입증합니다.


테스트 방법론

벤치마크의 공정성과 재현성을 보장하기 위해 다음 방법론을 적용했습니다.

항목설명
워밍업측정 전 3회의 워밍업 이터레이션을 실행하고 결과를 폐기합니다. 이를 통해 OPcache와 JIT가 완전히 워밍업됩니다.
이터레이션시나리오별 20회 측정 후 중앙값(median)을 보고합니다. 중앙값은 이상치(outlier) 노이즈를 제거하기 위해 사용됩니다.
시간 측정hrtime(true)를 사용하여 나노초 정밀도의 벽시계 시간(wall-clock time)을 측정합니다. microtime()의 클록 드리프트 문제를 방지합니다.
메모리 측정memory_get_peak_usage(true)로 PHP 런타임이 할당한 실제(RSS) 피크 메모리를 측정합니다.
파일 크기출력을 임시 파일에 기록하고 filesize()로 측정합니다.
격리 환경각 벤치마크는 자체 프로세스에서 실행하여 테스트 간 메모리 오염을 방지합니다.
동일 환경모든 라이브러리가 동일한 Docker 컨테이너에서 동일한 PHP 설정, CPU 제한, 메모리 제한으로 실행됩니다.
동일 입력모든 라이브러리가 동일한 입력 데이터(텍스트, 이미지, HTML)를 사용합니다.
공정한 설정각 라이브러리의 기본 설정(default configuration)을 사용합니다. 특정 라이브러리에 유리한 튜닝은 적용하지 않았습니다.

벤치마크 재현

벤치마크 스위트는 저장소에 포함되어 있습니다. 아래 Docker 명령어로 동일한 벤치마크를 직접 실행할 수 있습니다.

bash
# 1. 저장소 클론
git clone https://github.com/nicoapps/tcpdf-next.git
cd tcpdf-next

# 2. Docker 이미지 빌드 및 벤치마크 실행
cd benchmark
docker compose up --build

# 3. 또는 개별 시나리오 실행
docker build -t tcpdf-bench -f benchmark/Dockerfile .

docker run --rm --cpus=4 --memory=16g tcpdf-bench \
  php benchmark/run.php --scenario=simple

docker run --rm --cpus=4 --memory=16g tcpdf-bench \
  php benchmark/run.php --scenario=invoice

docker run --rm --cpus=4 --memory=16g tcpdf-bench \
  php benchmark/run.php --scenario=100page

docker run --rm --cpus=4 --memory=16g tcpdf-bench \
  php benchmark/run.php --scenario=html2pdf

# 4. 처리량 테스트 (4 워커)
docker run --rm --cpus=4 --memory=16g tcpdf-bench \
  php benchmark/run.php --throughput --workers=4

# 5. 결과를 JSON으로 내보내기
docker run --rm --cpus=4 --memory=16g tcpdf-bench \
  php benchmark/run.php --all --format=json > results.json

결과는 실행 종료 시 stdout으로 출력됩니다. Docker 설정으로 호스트 OS에 관계없이 동일한 환경이 보장됩니다.

INFO

벤치마크 실행에는 약 10~15분이 소요됩니다. --scenario 옵션으로 특정 시나리오만 실행하면 시간을 단축할 수 있습니다.


관련 문서

LGPL-3.0-or-later 라이선스로 배포됩니다.