mirror of
https://github.com/ZeroHawkeye/wordZero.git
synced 2025-09-26 20:01:17 +08:00
328 lines
10 KiB
Python
328 lines
10 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
Python Word操作性能基准测试
|
||
|
||
使用python-docx库进行Word文档操作的性能测试,
|
||
与Golang WordZero库进行对比。
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import time
|
||
import json
|
||
import tracemalloc
|
||
import psutil
|
||
from pathlib import Path
|
||
from typing import List, Dict, Any
|
||
from datetime import datetime
|
||
|
||
import pytest
|
||
from docx import Document
|
||
from docx.shared import Inches, Pt, RGBColor
|
||
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
||
from docx.enum.table import WD_TABLE_ALIGNMENT
|
||
|
||
# 确保输出目录存在
|
||
OUTPUT_DIR = Path("../results/python")
|
||
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
||
|
||
# 统一的测试配置,与其他语言保持一致
|
||
TEST_ITERATIONS = {
|
||
"basic": 50, # 基础文档创建
|
||
"complex": 30, # 复杂格式化
|
||
"table": 20, # 表格操作
|
||
"largeTable": 10, # 大表格处理
|
||
"largeDoc": 5, # 大型文档
|
||
"memory": 10, # 内存使用测试
|
||
}
|
||
|
||
|
||
class PerformanceTester:
|
||
"""性能测试工具类"""
|
||
|
||
def __init__(self):
|
||
self.results = []
|
||
|
||
def run_test(self, name: str, test_function, iterations: int = 10):
|
||
"""运行性能测试"""
|
||
print(f"\n开始测试: {name}")
|
||
times = []
|
||
|
||
for i in range(iterations):
|
||
start_time = time.perf_counter()
|
||
test_function(i)
|
||
end_time = time.perf_counter()
|
||
|
||
duration = (end_time - start_time) * 1000 # 转换为毫秒
|
||
times.append(duration)
|
||
|
||
if i % max(1, iterations // 10) == 0:
|
||
print(f" 进度: {i + 1}/{iterations}")
|
||
|
||
avg_time = sum(times) / len(times)
|
||
min_time = min(times)
|
||
max_time = max(times)
|
||
|
||
result = {
|
||
'name': name,
|
||
'avgTime': round(avg_time, 2),
|
||
'minTime': round(min_time, 2),
|
||
'maxTime': round(max_time, 2),
|
||
'iterations': iterations
|
||
}
|
||
|
||
self.results.append(result)
|
||
print(f" 平均耗时: {result['avgTime']}ms")
|
||
print(f" 最小耗时: {result['minTime']}ms")
|
||
print(f" 最大耗时: {result['maxTime']}ms")
|
||
|
||
return result
|
||
|
||
def generate_report(self):
|
||
"""生成性能测试报告"""
|
||
print('\n=== Python 性能测试报告 ===')
|
||
for result in self.results:
|
||
print(f"{result['name']}: {result['avgTime']}ms (平均)")
|
||
|
||
# 保存详细报告
|
||
report_path = OUTPUT_DIR / 'performance_report.json'
|
||
report_data = {
|
||
'timestamp': datetime.now().isoformat(),
|
||
'platform': 'Python',
|
||
'pythonVersion': f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
||
'results': self.results
|
||
}
|
||
|
||
with open(report_path, 'w', encoding='utf-8') as f:
|
||
json.dump(report_data, f, indent=2, ensure_ascii=False)
|
||
|
||
print(f"\n详细报告已保存到: {report_path}")
|
||
|
||
|
||
def test_basic_document_creation(index: int):
|
||
"""基础文档创建测试"""
|
||
doc = Document()
|
||
doc.add_paragraph("这是一个基础性能测试文档")
|
||
doc.add_paragraph("测试内容包括基本的文本添加功能")
|
||
|
||
filename = OUTPUT_DIR / f"basic_doc_{index}.docx"
|
||
doc.save(filename)
|
||
|
||
|
||
def test_complex_formatting(index: int):
|
||
"""复杂格式化测试"""
|
||
doc = Document()
|
||
|
||
# 添加标题
|
||
title = doc.add_heading("性能测试报告", level=1)
|
||
subtitle = doc.add_heading("测试概述", level=2)
|
||
|
||
# 添加格式化文本
|
||
para = doc.add_paragraph()
|
||
|
||
# 粗体文本
|
||
run = para.add_run("粗体文本")
|
||
run.bold = True
|
||
|
||
para.add_run(" ")
|
||
|
||
# 斜体文本
|
||
run = para.add_run("斜体文本")
|
||
run.italic = True
|
||
|
||
para.add_run(" ")
|
||
|
||
# 彩色文本
|
||
run = para.add_run("彩色文本")
|
||
run.font.color.rgb = RGBColor(255, 0, 0) # 红色
|
||
|
||
# 添加多个格式化段落
|
||
for j in range(10):
|
||
para = doc.add_paragraph(f"这是第{j + 1}个段落,包含复杂格式化")
|
||
para.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||
|
||
filename = OUTPUT_DIR / f"complex_formatting_{index}.docx"
|
||
doc.save(filename)
|
||
|
||
|
||
def test_table_operations(index: int):
|
||
"""表格操作测试"""
|
||
doc = Document()
|
||
|
||
# 添加标题
|
||
doc.add_heading("表格性能测试", level=1)
|
||
|
||
# 创建10行5列的表格
|
||
table = doc.add_table(rows=10, cols=5)
|
||
table.alignment = WD_TABLE_ALIGNMENT.CENTER
|
||
|
||
# 填充表格数据
|
||
for row_idx, row in enumerate(table.rows):
|
||
for col_idx, cell in enumerate(row.cells):
|
||
cell.text = f"R{row_idx + 1}C{col_idx + 1}"
|
||
|
||
filename = OUTPUT_DIR / f"table_operations_{index}.docx"
|
||
doc.save(filename)
|
||
|
||
|
||
def test_large_table(index: int):
|
||
"""大表格测试"""
|
||
doc = Document()
|
||
|
||
# 添加标题
|
||
doc.add_heading("大表格性能测试", level=1)
|
||
|
||
# 创建100行10列的大表格
|
||
table = doc.add_table(rows=100, cols=10)
|
||
table.alignment = WD_TABLE_ALIGNMENT.CENTER
|
||
|
||
# 填充表格数据
|
||
for row_idx, row in enumerate(table.rows):
|
||
for col_idx, cell in enumerate(row.cells):
|
||
cell.text = f"数据_{row_idx + 1}_{col_idx + 1}"
|
||
|
||
filename = OUTPUT_DIR / f"large_table_{index}.docx"
|
||
doc.save(filename)
|
||
|
||
|
||
def test_large_document(index: int):
|
||
"""大型文档测试"""
|
||
doc = Document()
|
||
|
||
# 添加主标题
|
||
doc.add_heading("大型文档性能测试", level=1)
|
||
|
||
# 添加1000个段落
|
||
for j in range(1000):
|
||
if j % 10 == 0:
|
||
# 每10个段落添加一个标题
|
||
doc.add_heading(f"章节 {j // 10 + 1}", level=2)
|
||
|
||
doc.add_paragraph(
|
||
f"这是第{j + 1}个段落。Lorem ipsum dolor sit amet, consectetur "
|
||
f"adipiscing elit. Sed do eiusmod tempor incididunt ut labore et "
|
||
f"dolore magna aliqua."
|
||
)
|
||
|
||
# 添加一个中等大小的表格
|
||
table = doc.add_table(rows=20, cols=8)
|
||
for row_idx, row in enumerate(table.rows):
|
||
for col_idx, cell in enumerate(row.cells):
|
||
cell.text = f"表格数据{row_idx + 1}-{col_idx + 1}"
|
||
|
||
filename = OUTPUT_DIR / f"large_document_{index}.docx"
|
||
doc.save(filename)
|
||
|
||
|
||
def test_memory_usage(index: int):
|
||
"""内存使用测试"""
|
||
# 开始内存追踪
|
||
tracemalloc.start()
|
||
initial_memory = tracemalloc.get_traced_memory()[0]
|
||
|
||
doc = Document()
|
||
|
||
# 创建复杂内容
|
||
for j in range(100):
|
||
doc.add_paragraph(f"段落{j + 1}: 这是一个测试段落,用于测试内存使用情况")
|
||
|
||
# 添加表格
|
||
table = doc.add_table(rows=50, cols=6)
|
||
for row_idx, row in enumerate(table.rows):
|
||
for col_idx, cell in enumerate(row.cells):
|
||
cell.text = f"单元格{row_idx + 1}-{col_idx + 1}"
|
||
|
||
# 保存文档
|
||
filename = OUTPUT_DIR / f"memory_test_{index}.docx"
|
||
doc.save(filename)
|
||
|
||
# 检查内存使用
|
||
final_memory = tracemalloc.get_traced_memory()[0]
|
||
if index == 0:
|
||
memory_used = (final_memory - initial_memory) / 1024 # 转换为KB
|
||
print(f" 内存使用: {memory_used:.0f}KB")
|
||
|
||
tracemalloc.stop()
|
||
|
||
|
||
# pytest benchmark 测试函数
|
||
def test_benchmark_basic_document(benchmark):
|
||
"""pytest-benchmark: 基础文档创建"""
|
||
benchmark(test_basic_document_creation, 0)
|
||
|
||
|
||
def test_benchmark_complex_formatting(benchmark):
|
||
"""pytest-benchmark: 复杂格式化"""
|
||
benchmark(test_complex_formatting, 0)
|
||
|
||
|
||
def test_benchmark_table_operations(benchmark):
|
||
"""pytest-benchmark: 表格操作"""
|
||
benchmark(test_table_operations, 0)
|
||
|
||
|
||
def test_benchmark_large_table(benchmark):
|
||
"""pytest-benchmark: 大表格"""
|
||
benchmark(test_large_table, 0)
|
||
|
||
|
||
def test_benchmark_large_document(benchmark):
|
||
"""pytest-benchmark: 大型文档"""
|
||
benchmark(test_large_document, 0)
|
||
|
||
|
||
def test_benchmark_memory_usage(benchmark):
|
||
"""pytest-benchmark: 内存使用"""
|
||
benchmark(test_memory_usage, 0)
|
||
|
||
|
||
class TestPerformanceComparison:
|
||
"""性能对比测试类"""
|
||
|
||
def test_performance_comparison(self):
|
||
"""运行完整的性能对比测试"""
|
||
print('开始 Python (python-docx库) 性能基准测试...')
|
||
print(f'Python 版本: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')
|
||
print(f'输出目录: {OUTPUT_DIR}')
|
||
|
||
tester = PerformanceTester()
|
||
|
||
# 运行各项测试(使用统一的迭代次数配置)
|
||
tester.run_test('基础文档创建', test_basic_document_creation, TEST_ITERATIONS["basic"])
|
||
tester.run_test('复杂格式化', test_complex_formatting, TEST_ITERATIONS["complex"])
|
||
tester.run_test('表格操作', test_table_operations, TEST_ITERATIONS["table"])
|
||
tester.run_test('大表格处理', test_large_table, TEST_ITERATIONS["largeTable"])
|
||
tester.run_test('大型文档', test_large_document, TEST_ITERATIONS["largeDoc"])
|
||
tester.run_test('内存使用测试', test_memory_usage, TEST_ITERATIONS["memory"])
|
||
|
||
# 生成报告
|
||
tester.generate_report()
|
||
|
||
|
||
def main():
|
||
"""主函数,直接运行时执行"""
|
||
print("开始 Python 性能基准测试...")
|
||
|
||
tester = PerformanceTester()
|
||
|
||
try:
|
||
# 使用统一的迭代次数配置
|
||
tester.run_test('基础文档创建', test_basic_document_creation, TEST_ITERATIONS["basic"])
|
||
tester.run_test('复杂格式化', test_complex_formatting, TEST_ITERATIONS["complex"])
|
||
tester.run_test('表格操作', test_table_operations, TEST_ITERATIONS["table"])
|
||
tester.run_test('大表格处理', test_large_table, TEST_ITERATIONS["largeTable"])
|
||
tester.run_test('大型文档', test_large_document, TEST_ITERATIONS["largeDoc"])
|
||
tester.run_test('内存使用测试', test_memory_usage, TEST_ITERATIONS["memory"])
|
||
|
||
tester.generate_report()
|
||
|
||
print('\n所有测试完成!')
|
||
|
||
except Exception as e:
|
||
print(f'测试过程中发生错误: {e}')
|
||
raise
|
||
|
||
|
||
if __name__ == '__main__':
|
||
main() |