"""基准测试:不同 DPI 下的 PDF 渲染耗时 vs OCR 耗时 vs 识别准确度""" import sys import time from pathlib import Path try: sys.stdout.reconfigure(encoding="utf-8") except Exception: pass ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT)) import fitz from app.core import warmup from app.services.recognize_service import recognize_file def render(pdf_path: Path, dpi: int) -> Path: out = ROOT / f"_bench_{dpi}dpi.png" doc = fitz.open(str(pdf_path)) page = doc[0] pix = page.get_pixmap(matrix=fitz.Matrix(dpi / 72, dpi / 72), alpha=False) pix.save(str(out)) doc.close() return out def bench_dpi(pdf_path: Path, dpi: int, runs: int = 3): img_path = render(pdf_path, dpi) img_bytes = img_path.read_bytes() print(f"\n--- DPI={dpi} | 渲染图 {img_path.stat().st_size//1024}KB ---") times = [] fields_ok = None for i in range(runs): t0 = time.time() result = recognize_file(img_path.name, img_bytes) elapsed = (time.time() - t0) * 1000 times.append(elapsed) if i == 0 and result.success: fields_ok = result.fields print(f" run {i+1}: {elapsed:7.1f}ms success={result.success}") # 清理中间文件 img_path.unlink(missing_ok=True) (ROOT / f".{img_path.stem}_pages").rmdir() if (ROOT / f".{img_path.stem}_pages").exists() else None # 上面可能删不了子目录,try 再清理 _pages 下文件 pages_dir = ROOT / f".{img_path.stem}_pages" if pages_dir.exists(): for f in pages_dir.glob("*"): f.unlink(missing_ok=True) pages_dir.rmdir() times.sort() print(f" min={times[0]:.1f}ms median={times[len(times)//2]:.1f}ms max={times[-1]:.1f}ms") return fields_ok if __name__ == "__main__": pdf = ROOT / "fapiao.pdf" print(f"PDF: {pdf.name}, {pdf.stat().st_size//1024}KB, 1 页") warmup() print("预热完成\n") print("=" * 60) fields_100 = bench_dpi(pdf, 100) print("=" * 60) fields_150 = bench_dpi(pdf, 150) print("=" * 60) fields_200 = bench_dpi(pdf, 200) print("=" * 60) fields_300 = bench_dpi(pdf, 300) print("=" * 60) # 汇总 print("\n\n=== 关键字段对比 ===") print(f"{'字段':<15} {'100dpi':<25} {'150dpi':<25} {'200dpi':<25} {'300dpi':<25}") key_fields = ["invoice_no", "invoice_date", "amount", "amount_cn", "amount_pretax", "tax_amount", "seller_name", "buyer_name", "seller_tax_no", "buyer_tax_no", "amount_match"] for k in key_fields: row = [k] for f in [fields_100, fields_150, fields_200, fields_300]: v = getattr(f, k) if f else None if v is None: row.append("(空)") else: s = str(v)[:23] row.append(s) print(f"{row[0]:<15} {row[1]:<25} {row[2]:<25} {row[3]:<25} {row[4]:<25}")