【自动化系列】003:系统性能基准测试工具

41 阅读13分钟

功能介绍

这是一个全面的系统性能基准测试工具,用于评估和比较计算机系统的各项性能指标。该工具具备以下核心功能:

  1. 多维度性能测试

    • CPU计算性能测试
    • 内存读写性能测试
    • 磁盘I/O性能测试
    • 网络带宽测试
    • 图形渲染性能测试
  2. 标准化测试套件

    • 经典算法测试(素数计算、斐波那契数列等)
    • 加密解密性能测试
    • 压缩解压性能测试
    • 数据库查询性能测试
    • Web服务器响应测试
  3. 详细结果分析

    • 性能指标量化评分
    • 测试结果可视化图表
    • 历史数据对比分析
    • 性能趋势跟踪
    • 异常检测和报告
  4. 灵活的测试配置

    • 自定义测试项目和权重
    • 测试时长和并发数设置
    • 硬件资源限制配置
    • 测试环境信息收集
    • 多种输出格式支持
  5. 自动化测试调度

    • 定时基准测试
    • 性能退化监控
    • 自动报告生成
    • 性能阈值告警
    • 集成CI/CD流水线

场景应用

1. 硬件采购决策

  • 对比不同硬件配置的性能表现
  • 评估升级硬件的投资回报率
  • 验证硬件规格是否符合预期

2. 系统优化验证

  • 评估系统调优效果
  • 对比不同配置方案性能
  • 验证软件更新对性能的影响

3. 云服务选型

  • 对比不同云服务商性能
  • 评估不同实例类型的性价比
  • 监控云服务性能稳定性

4. 应用性能监控

  • 监控应用性能基线
  • 检测性能退化趋势
  • 验证容量规划准确性

报错处理

1. 测试执行异常

try:
    result = test_executor.run_test(test_case)
    if not result.success:
        logger.error(f"测试执行失败: {result.error_message}")
        handle_test_failure(test_case, result.error_message)
except TimeoutError as e:
    logger.error(f"测试超时: {test_case.name}")
    mark_test_timeout(test_case)
except ResourceExhaustedError as e:
    logger.error(f"资源不足: {str(e)}")
    adjust_test_resources(test_case)
except Exception as e:
    logger.error(f"测试执行异常: {str(e)}")
    report_test_exception(test_case, e)

2. 硬件访问异常

try:
    cpu_info = get_cpu_info()
except PermissionError as e:
    logger.error(f"无权限访问CPU信息: {str(e)}")
    raise BenchmarkError(f"硬件信息访问被拒绝: {str(e)}")
except NotImplementedError as e:
    logger.warning(f"不支持的硬件平台: {platform.system()}")
    cpu_info = get_fallback_cpu_info()
except Exception as e:
    logger.error(f"获取硬件信息异常: {str(e)}")
    cpu_info = {}

3. 网络测试异常

try:
    bandwidth = measure_network_bandwidth(server_url)
except requests.Timeout as e:
    logger.error(f"网络测试超时: {str(e)}")
    return {"success": False, "error": "网络连接超时"}
except requests.ConnectionError as e:
    logger.error(f"网络连接失败: {str(e)}")
    return {"success": False, "error": "网络连接失败"}
except Exception as e:
    logger.error(f"网络测试异常: {str(e)}")
    return {"success": False, "error": f"网络测试异常: {str(e)}"}

4. 数据存储异常

try:
    save_test_results(results)
except sqlite3.DatabaseError as e:
    logger.error(f"数据库操作失败: {str(e)}")
    # 尝试重新连接
    reconnect_database()
    retry_save_results(results)
except IOError as e:
    logger.error(f"文件写入失败: {str(e)}")
    # 检查磁盘空间
    check_disk_space()
    raise BenchmarkError(f"结果保存失败: {str(e)}")
except Exception as e:
    logger.error(f"数据存储异常: {str(e)}")

代码实现

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
系统性能基准测试工具
功能:全面评估系统性能指标
作者:Cline
版本:1.0
"""

import argparse
import sys
import json
import yaml
import logging
import os
import time
import threading
import subprocess
import multiprocessing
import platform
import psutil
import hashlib
import sqlite3
import csv
from datetime import datetime
from typing import Dict, List, Any, Optional, Callable
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import matplotlib.pyplot as plt
import numpy as np

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('benchmark.log'),
        logging.StreamHandler(sys.stdout)
    ]
)
logger = logging.getLogger(__name__)

class BenchmarkError(Exception):
    """基准测试异常类"""
    pass

class TestResult:
    """测试结果类"""
    def __init__(self, test_name: str, score: float = 0.0, duration: float = 0.0, 
                 metrics: Dict = None, success: bool = True, error: str = None):
        self.test_name = test_name
        self.score = score
        self.duration = duration
        self.metrics = metrics or {}
        self.success = success
        self.error = error
        self.timestamp = datetime.now()
        
    def to_dict(self):
        """转换为字典"""
        return {
            'test_name': self.test_name,
            'score': self.score,
            'duration': self.duration,
            'metrics': self.metrics,
            'success': self.success,
            'error': self.error,
            'timestamp': self.timestamp.isoformat()
        }

class SystemInfoCollector:
    """系统信息收集器"""
    @staticmethod
    def get_system_info() -> Dict:
        """获取系统基本信息"""
        try:
            info = {
                'platform': platform.system(),
                'platform_version': platform.version(),
                'platform_release': platform.release(),
                'architecture': platform.machine(),
                'hostname': platform.node(),
                'python_version': platform.python_version(),
                'cpu_count': psutil.cpu_count(logical=False),
                'logical_cpu_count': psutil.cpu_count(logical=True),
                'memory_total': psutil.virtual_memory().total,
                'swap_total': psutil.swap_memory().total,
                'boot_time': datetime.fromtimestamp(psutil.boot_time()).isoformat()
            }
            
            # CPU信息
            try:
                cpu_freq = psutil.cpu_freq()
                info['cpu_max_freq'] = cpu_freq.max if cpu_freq else None
                info['cpu_min_freq'] = cpu_freq.min if cpu_freq else None
            except Exception:
                info['cpu_max_freq'] = None
                info['cpu_min_freq'] = None
                
            # 磁盘信息
            disk_info = []
            for partition in psutil.disk_partitions():
                try:
                    usage = psutil.disk_usage(partition.mountpoint)
                    disk_info.append({
                        'device': partition.device,
                        'mountpoint': partition.mountpoint,
                        'total': usage.total,
                        'used': usage.used,
                        'free': usage.free
                    })
                except Exception:
                    continue
            info['disk_info'] = disk_info
            
            return info
        except Exception as e:
            logger.error(f"获取系统信息失败: {str(e)}")
            return {}

class CPUBenchmark:
    """CPU基准测试"""
    @staticmethod
    def prime_calculation(n: int = 10000) -> TestResult:
        """素数计算测试"""
        start_time = time.time()
        try:
            primes = []
            for num in range(2, n):
                is_prime = True
                for i in range(2, int(num ** 0.5) + 1):
                    if num % i == 0:
                        is_prime = False
                        break
                if is_prime:
                    primes.append(num)
            
            duration = time.time() - start_time
            # 计算得分(基于计算速度)
            score = len(primes) / duration
            
            return TestResult(
                test_name='prime_calculation',
                score=score,
                duration=duration,
                metrics={'primes_found': len(primes), 'range': n}
            )
        except Exception as e:
            duration = time.time() - start_time
            return TestResult(
                test_name='prime_calculation',
                score=0,
                duration=duration,
                success=False,
                error=str(e)
            )
            
    @staticmethod
    def fibonacci_calculation(n: int = 35) -> TestResult:
        """斐波那契数列计算测试"""
        start_time = time.time()
        try:
            def fib(x):
                if x <= 1:
                    return x
                return fib(x-1) + fib(x-2)
                
            result = fib(n)
            duration = time.time() - start_time
            # 计算得分(基于计算速度)
            score = n / duration
            
            return TestResult(
                test_name='fibonacci_calculation',
                score=score,
                duration=duration,
                metrics={'fibonacci_number': result, 'sequence_position': n}
            )
        except Exception as e:
            duration = time.time() - start_time
            return TestResult(
                test_name='fibonacci_calculation',
                score=0,
                duration=duration,
                success=False,
                error=str(e)
            )

class MemoryBenchmark:
    """内存基准测试"""
    @staticmethod
    def memory_read_write(size_mb: int = 100) -> TestResult:
        """内存读写测试"""
        start_time = time.time()
        try:
            # 创建测试数据
            size_bytes = size_mb * 1024 * 1024
            test_data = bytearray(os.urandom(size_bytes))
            
            # 读取测试
            read_start = time.time()
            checksum1 = hashlib.md5(test_data).hexdigest()
            read_duration = time.time() - read_start
            
            # 写入测试
            write_start = time.time()
            test_data_copy = bytearray(test_data)
            write_duration = time.time() - write_start
            
            total_duration = time.time() - start_time
            # 计算得分(MB/s)
            read_speed = size_mb / read_duration
            write_speed = size_mb / write_duration
            score = (read_speed + write_speed) / 2
            
            return TestResult(
                test_name='memory_read_write',
                score=score,
                duration=total_duration,
                metrics={
                    'size_mb': size_mb,
                    'read_speed': read_speed,
                    'write_speed': write_speed,
                    'read_duration': read_duration,
                    'write_duration': write_duration
                }
            )
        except Exception as e:
            duration = time.time() - start_time
            return TestResult(
                test_name='memory_read_write',
                score=0,
                duration=duration,
                success=False,
                error=str(e)
            )

class DiskBenchmark:
    """磁盘基准测试"""
    @staticmethod
    def disk_io_test(file_size_mb: int = 100, block_size_kb: int = 64) -> TestResult:
        """磁盘I/O测试"""
        start_time = time.time()
        test_file = 'benchmark_test.tmp'
        
        try:
            block_size = block_size_kb * 1024
            blocks = (file_size_mb * 1024 * 1024) // block_size
            
            # 写入测试
            write_start = time.time()
            with open(test_file, 'wb') as f:
                for _ in range(blocks):
                    f.write(os.urandom(block_size))
            write_duration = time.time() - write_start
            
            # 刷新到磁盘
            with open(test_file, 'rb') as f:
                f.flush()
                os.fsync(f.fileno())
            
            # 读取测试
            read_start = time.time()
            with open(test_file, 'rb') as f:
                while f.read(block_size):
                    pass
            read_duration = time.time() - read_start
            
            total_duration = time.time() - start_time
            
            # 计算得分(MB/s)
            write_speed = file_size_mb / write_duration
            read_speed = file_size_mb / read_duration
            score = (write_speed + read_speed) / 2
            
            # 清理测试文件
            try:
                os.remove(test_file)
            except Exception:
                pass
                
            return TestResult(
                test_name='disk_io_test',
                score=score,
                duration=total_duration,
                metrics={
                    'file_size_mb': file_size_mb,
                    'block_size_kb': block_size_kb,
                    'write_speed': write_speed,
                    'read_speed': read_speed,
                    'write_duration': write_duration,
                    'read_duration': read_duration
                }
            )
        except Exception as e:
            duration = time.time() - start_time
            # 清理测试文件
            try:
                os.remove(test_file)
            except Exception:
                pass
            return TestResult(
                test_name='disk_io_test',
                score=0,
                duration=duration,
                success=False,
                error=str(e)
            )

class NetworkBenchmark:
    """网络基准测试"""
    @staticmethod
    def network_bandwidth_test(server_url: str = 'http://speedtest.tele2.net/1MB.zip') -> TestResult:
        """网络带宽测试"""
        start_time = time.time()
        try:
            import requests
            from urllib.parse import urlparse
            
            # 解析URL获取文件大小
            parsed_url = urlparse(server_url)
            filename = os.path.basename(parsed_url.path)
            
            # 下载测试
            download_start = time.time()
            response = requests.get(server_url, stream=True, timeout=30)
            response.raise_for_status()
            
            total_size = 0
            for chunk in response.iter_content(chunk_size=8192):
                total_size += len(chunk)
            
            download_duration = time.time() - download_start
            total_duration = time.time() - start_time
            
            # 计算得分(Mbps)
            file_size_mb = total_size / (1024 * 1024)
            download_speed = (file_size_mb * 8) / download_duration  # Mbps
            score = download_speed
            
            return TestResult(
                test_name='network_bandwidth_test',
                score=score,
                duration=total_duration,
                metrics={
                    'downloaded_size_mb': file_size_mb,
                    'download_duration': download_duration,
                    'download_speed_mbps': download_speed,
                    'server_url': server_url
                }
            )
        except Exception as e:
            duration = time.time() - start_time
            return TestResult(
                test_name='network_bandwidth_test',
                score=0,
                duration=duration,
                success=False,
                error=str(e)
            )

class BenchmarkSuite:
    """基准测试套件"""
    def __init__(self, config: Dict = None):
        self.config = config or {}
        self.results = []
        self.system_info = {}
        
    def run_all_tests(self) -> List[TestResult]:
        """运行所有测试"""
        logger.info("开始执行基准测试套件...")
        
        # 收集系统信息
        self.system_info = SystemInfoCollector.get_system_info()
        logger.info(f"系统信息收集完成: {self.system_info.get('platform', 'Unknown')}")
        
        # 定义测试项目
        tests = [
            # CPU测试
            (CPUBenchmark.prime_calculation, {'n': 10000}),
            (CPUBenchmark.fibonacci_calculation, {'n': 30}),
            
            # 内存测试
            (MemoryBenchmark.memory_read_write, {'size_mb': 50}),
            
            # 磁盘测试
            (DiskBenchmark.disk_io_test, {'file_size_mb': 50, 'block_size_kb': 64}),
            
            # 网络测试
            (NetworkBenchmark.network_bandwidth_test, {})
        ]
        
        # 执行测试
        with ThreadPoolExecutor(max_workers=3) as executor:
            futures = []
            for test_func, kwargs in tests:
                future = executor.submit(self._run_single_test, test_func, kwargs)
                futures.append((future, test_func.__name__))
                
            # 收集结果
            for future, test_name in futures:
                try:
                    result = future.result(timeout=60)  # 60秒超时
                    self.results.append(result)
                    if result.success:
                        logger.info(f"测试 {test_name} 完成,得分: {result.score:.2f}")
                    else:
                        logger.error(f"测试 {test_name} 失败: {result.error}")
                except Exception as e:
                    logger.error(f"测试 {test_name} 执行异常: {str(e)}")
                    self.results.append(TestResult(
                        test_name=test_name,
                        score=0,
                        duration=0,
                        success=False,
                        error=f"执行异常: {str(e)}"
                    ))
                    
        logger.info("基准测试套件执行完成")
        return self.results
        
    def _run_single_test(self, test_func: Callable, kwargs: Dict) -> TestResult:
        """运行单个测试"""
        try:
            return test_func(**kwargs)
        except Exception as e:
            return TestResult(
                test_name=test_func.__name__,
                score=0,
                duration=0,
                success=False,
                error=str(e)
            )
            
    def calculate_overall_score(self) -> float:
        """计算综合得分"""
        if not self.results:
            return 0.0
            
        total_score = 0.0
        valid_tests = 0
        
        for result in self.results:
            if result.success:
                total_score += result.score
                valid_tests += 1
                
        return total_score / valid_tests if valid_tests > 0 else 0.0
        
    def generate_report(self) -> Dict:
        """生成测试报告"""
        overall_score = self.calculate_overall_score()
        
        report = {
            'system_info': self.system_info,
            'overall_score': overall_score,
            'test_results': [result.to_dict() for result in self.results],
            'generated_at': datetime.now().isoformat()
        }
        
        return report

class ReportGenerator:
    """报告生成器"""
    @staticmethod
    def save_json_report(report: Dict, filename: str = None):
        """保存JSON格式报告"""
        if not filename:
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            filename = f'benchmark_report_{timestamp}.json'
            
        try:
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(report, f, indent=2, ensure_ascii=False)
            logger.info(f"JSON报告已保存: {filename}")
        except Exception as e:
            logger.error(f"保存JSON报告失败: {str(e)}")
            
    @staticmethod
    def save_csv_report(report: Dict, filename: str = None):
        """保存CSV格式报告"""
        if not filename:
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            filename = f'benchmark_report_{timestamp}.csv'
            
        try:
            with open(filename, 'w', newline='', encoding='utf-8') as f:
                writer = csv.writer(f)
                writer.writerow(['Test Name', 'Score', 'Duration', 'Success', 'Error'])
                
                for result in report.get('test_results', []):
                    writer.writerow([
                        result.get('test_name', ''),
                        result.get('score', 0),
                        result.get('duration', 0),
                        result.get('success', False),
                        result.get('error', '')
                    ])
            logger.info(f"CSV报告已保存: {filename}")
        except Exception as e:
            logger.error(f"保存CSV报告失败: {str(e)}")
            
    @staticmethod
    def generate_charts(report: Dict, output_dir: str = 'charts'):
        """生成图表"""
        try:
            # 创建输出目录
            os.makedirs(output_dir, exist_ok=True)
            
            # 提取测试结果数据
            test_names = []
            scores = []
            durations = []
            
            for result in report.get('test_results', []):
                if result.get('success', False):
                    test_names.append(result.get('test_name', 'Unknown'))
                    scores.append(result.get('score', 0))
                    durations.append(result.get('duration', 0))
                    
            if not test_names:
                logger.warning("没有有效的测试结果用于生成图表")
                return
                
            # 生成得分柱状图
            plt.figure(figsize=(10, 6))
            bars = plt.bar(range(len(test_names)), scores, color='skyblue')
            plt.xlabel('测试项目')
            plt.ylabel('得分')
            plt.title('基准测试得分')
            plt.xticks(range(len(test_names)), test_names, rotation=45, ha='right')
            
            # 在柱状图上添加数值标签
            for bar, score in zip(bars, scores):
                plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + max(scores)*0.01,
                        f'{score:.2f}', ha='center', va='bottom')
                
            plt.tight_layout()
            plt.savefig(os.path.join(output_dir, 'benchmark_scores.png'))
            plt.close()
            
            # 生成执行时间柱状图
            plt.figure(figsize=(10, 6))
            bars = plt.bar(range(len(test_names)), durations, color='lightcoral')
            plt.xlabel('测试项目')
            plt.ylabel('执行时间 (秒)')
            plt.title('测试执行时间')
            plt.xticks(range(len(test_names)), test_names, rotation=45, ha='right')
            
            # 在柱状图上添加数值标签
            for bar, duration in zip(bars, durations):
                plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + max(durations)*0.01,
                        f'{duration:.2f}s', ha='center', va='bottom')
                
            plt.tight_layout()
            plt.savefig(os.path.join(output_dir, 'benchmark_durations.png'))
            plt.close()
            
            logger.info(f"图表已生成到目录: {output_dir}")
            
        except Exception as e:
            logger.error(f"生成图表失败: {str(e)}")

class DatabaseManager:
    """数据库管理器"""
    def __init__(self, db_path: str = 'benchmark_history.db'):
        self.db_path = db_path
        self.init_database()
        
    def init_database(self):
        """初始化数据库"""
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            
            # 创建测试结果表
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS benchmark_results (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    timestamp TEXT NOT NULL,
                    overall_score REAL NOT NULL,
                    system_info TEXT,
                    test_results TEXT,
                    tags TEXT
                )
            ''')
            
            conn.commit()
            conn.close()
            logger.info("数据库初始化完成")
            
        except Exception as e:
            logger.error(f"数据库初始化失败: {str(e)}")
            
    def save_result(self, report: Dict, tags: List[str] = None):
        """保存测试结果"""
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            
            cursor.execute('''
                INSERT INTO benchmark_results 
                (timestamp, overall_score, system_info, test_results, tags)
                VALUES (?, ?, ?, ?, ?)
            ''', (
                report.get('generated_at', ''),
                report.get('overall_score', 0),
                json.dumps(report.get('system_info', {})),
                json.dumps(report.get('test_results', [])),
                ','.join(tags) if tags else ''
            ))
            
            conn.commit()
            conn.close()
            logger.info("测试结果已保存到数据库")
            
        except Exception as e:
            logger.error(f"保存测试结果到数据库失败: {str(e)}")
            
    def get_history(self, limit: int = 10) -> List[Dict]:
        """获取历史测试结果"""
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            
            cursor.execute('''
                SELECT timestamp, overall_score, system_info, test_results, tags
                FROM benchmark_results
                ORDER BY timestamp DESC
                LIMIT ?
            ''', (limit,))
            
            rows = cursor.fetchall()
            conn.close()
            
            results = []
            for row in rows:
                results.append({
                    'timestamp': row[0],
                    'overall_score': row[1],
                    'system_info': json.loads(row[2]) if row[2] else {},
                    'test_results': json.loads(row[3]) if row[3] else [],
                    'tags': row[4].split(',') if row[4] else []
                })
                
            return results
            
        except Exception as e:
            logger.error(f"获取历史测试结果失败: {str(e)}")
            return []

def create_sample_config():
    """创建示例配置文件"""
    sample_config = {
        "tests": {
            "cpu": {
                "prime_calculation": {"n": 10000},
                "fibonacci_calculation": {"n": 30}
            },
            "memory": {
                "memory_read_write": {"size_mb": 50}
            },
            "disk": {
                "disk_io_test": {"file_size_mb": 50, "block_size_kb": 64}
            },
            "network": {
                "network_bandwidth_test": {"server_url": "http://speedtest.tele2.net/1MB.zip"}
            }
        },
        "settings": {
            "timeout": 60,
            "parallel_tests": 3,
            "output_formats": ["json", "csv"],
            "save_to_database": True,
            "generate_charts": True
        },
        "tags": ["baseline", "performance"]
    }
    
    with open('benchmark_sample_config.json', 'w', encoding='utf-8') as f:
        json.dump(sample_config, f, indent=2, ensure_ascii=False)
    logger.info("示例配置文件已创建: benchmark_sample_config.json")

def compare_results(results1: Dict, results2: Dict) -> Dict:
    """比较两次测试结果"""
    comparison = {
        'timestamp1': results1.get('generated_at', ''),
        'timestamp2': results2.get('generated_at', ''),
        'overall_score_diff': results2.get('overall_score', 0) - results1.get('overall_score', 0),
        'test_comparisons': []
    }
    
    # 创建结果映射
    results1_map = {r['test_name']: r for r in results1.get('test_results', [])}
    results2_map = {r['test_name']: r for r in results2.get('test_results', [])}
    
    # 比较每个测试项目
    all_test_names = set(results1_map.keys()) | set(results2_map.keys())
    for test_name in all_test_names:
        result1 = results1_map.get(test_name)
        result2 = results2_map.get(test_name)
        
        comparison_item = {
            'test_name': test_name,
            'score1': result1.get('score', 0) if result1 else 0,
            'score2': result2.get('score', 0) if result2 else 0,
            'score_diff': 0,
            'improved': None
        }
        
        if result1 and result2:
            score_diff = result2.get('score', 0) - result1.get('score', 0)
            comparison_item['score_diff'] = score_diff
            comparison_item['improved'] = score_diff > 0
            
        comparison['test_comparisons'].append(comparison_item)
        
    return comparison

def main():
    parser = argparse.ArgumentParser(description='系统性能基准测试工具')
    parser.add_argument('-c', '--config', help='配置文件路径')
    parser.add_argument('--run', action='store_true', help='运行基准测试')
    parser.add_argument('--sample-config', action='store_true', help='创建示例配置文件')
    parser.add_argument('--compare', nargs=2, metavar=('REPORT1', 'REPORT2'), 
                       help='比较两个测试报告')
    parser.add_argument('--history', action='store_true', help='查看历史测试结果')
    parser.add_argument('--limit', type=int, default=10, help='历史记录数量限制')
    
    args = parser.parse_args()
    
    if args.sample_config:
        create_sample_config()
        return
        
    if args.compare:
        try:
            with open(args.compare[0], 'r', encoding='utf-8') as f:
                report1 = json.load(f)
            with open(args.compare[1], 'r', encoding='utf-8') as f:
                report2 = json.load(f)
                
            comparison = compare_results(report1, report2)
            print(json.dumps(comparison, indent=2, ensure_ascii=False))
        except Exception as e:
            logger.error(f"比较测试报告失败: {str(e)}")
        return
        
    if args.history:
        db_manager = DatabaseManager()
        history = db_manager.get_history(args.limit)
        print(json.dumps(history, indent=2, ensure_ascii=False))
        return
        
    if args.run:
        # 运行基准测试
        suite = BenchmarkSuite()
        results = suite.run_all_tests()
        report = suite.generate_report()
        
        # 保存报告
        ReportGenerator.save_json_report(report)
        ReportGenerator.save_csv_report(report)
        ReportGenerator.generate_charts(report)
        
        # 保存到数据库
        db_manager = DatabaseManager()
        db_manager.save_result(report)
        
        # 输出综合得分
        overall_score = report.get('overall_score', 0)
        print(f"\n综合性能得分: {overall_score:.2f}")
        
        # 输出详细结果
        print("\n详细测试结果:")
        for result in results:
            status = "✓" if result.success else "✗"
            print(f"  {status} {result.test_name}: {result.score:.2f} "
                  f"(耗时: {result.duration:.2f}s)")
            if not result.success:
                print(f"    错误: {result.error}")
                
    else:
        parser.print_help()

if __name__ == '__main__':
    main()

使用说明

1. 安装依赖

pip install psutil matplotlib numpy requests pyyaml

2. 创建配置文件

python benchmark_tool.py --sample-config

3. 运行基准测试

python benchmark_tool.py --run

4. 查看历史结果

python benchmark_tool.py --history --limit 5

5. 比较测试结果

python benchmark_tool.py --compare report1.json report2.json

配置文件示例

JSON配置文件

{
  "tests": {
    "cpu": {
      "prime_calculation": {"n": 10000},
      "fibonacci_calculation": {"n": 30}
    },
    "memory": {
      "memory_read_write": {"size_mb": 50}
    },
    "disk": {
      "disk_io_test": {"file_size_mb": 50, "block_size_kb": 64}
    },
    "network": {
      "network_bandwidth_test": {"server_url": "http://speedtest.tele2.net/1MB.zip"}
    }
  },
  "settings": {
    "timeout": 60,
    "parallel_tests": 3,
    "output_formats": ["json", "csv"],
    "save_to_database": true,
    "generate_charts": true
  },
  "tags": ["baseline", "performance"]
}

高级特性

1. 多维度性能评估

提供CPU、内存、磁盘、网络等多个维度的性能测试,全面评估系统性能。

2. 历史数据追踪

内置数据库存储历史测试结果,支持性能趋势分析和退化检测。

3. 可视化报告

自动生成图表和报告,直观展示测试结果和性能对比。

4. 灵活的测试配置

支持自定义测试参数和权重,适应不同的测试需求。

最佳实践

1. 测试环境准备

  • 关闭不必要的应用程序和服务
  • 确保系统处于稳定状态
  • 多次测试取平均值以提高准确性

2. 结果解读

  • 关注综合得分变化趋势
  • 分析单项测试结果差异
  • 结合系统信息判断性能瓶颈

3. 定期测试

  • 建立定期基准测试计划
  • 在系统变更前后进行测试
  • 设置性能阈值告警

总结

这个系统性能基准测试工具提供了一个全面、准确的系统性能评估解决方案。通过多维度的测试项目和详细的分析报告,可以帮助用户深入了解系统性能状况,为硬件升级、系统优化和性能监控提供有力支持。