"""性能测试和基准测试

This module contains performance tests and benchmarks for the type conversion functions.
"""

import time
import random
import sys
import os

# 添加项目根目录到Python路径
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from e2e_type_converter import (
    e2e_list, e2e_str, e2e_int, e2e_float, e2e_dict, e2e_set, e2e_tuple,
    TypeConverter
)

# 尝试导入numpy
try:
    import numpy as np
    numpy_available = True
except ImportError:
    numpy_available = False

# 测试数据生成
def generate_test_data():
    """生成测试数据
    
    Returns:
        dict: 包含各种类型测试数据的字典
    """
    data = {
        'int': 42,
        'float': 3.14,
        'bool': True,
        'str': 'Hello, World!',
        'bytes': b'Hello, World!',
        'list': [1, 2, 3, 4, 5],
        'tuple': (1, 2, 3, 4, 5),
        'dict': {'a': 1, 'b': 2, 'c': 3},
        'set': {1, 2, 3, 4, 5},
        'none': None,
    }
    
    # 仅当numpy可用时添加numpy测试数据
    if numpy_available:
        data.update({
            'numpy_array': np.array([1, 2, 3, 4, 5]),
            'numpy_2darray': np.array([[1, 2, 3], [4, 5, 6]]),
            'numpy_scalar': np.array(42).item(),
        })
    
    return data

# 性能测试装饰器
def benchmark(func, *args, **kwargs):
    """基准测试装饰器
    
    Args:
        func: 要测试的函数
        *args: 函数参数
        **kwargs: 函数关键字参数
        
    Returns:
        tuple: (执行时间, 函数返回值)
    """
    start_time = time.perf_counter()
    result = func(*args, **kwargs)
    end_time = time.perf_counter()
    return end_time - start_time, result

# 批量测试
def batch_benchmark(func, data, iterations=10000):
    """批量测试函数性能
    
    Args:
        func: 要测试的函数
        data: 测试数据
        iterations: 迭代次数
        
    Returns:
        float: 平均执行时间（秒）
    """
    total_time = 0
    for _ in range(iterations):
        start_time = time.perf_counter()
        func(data)
        end_time = time.perf_counter()
        total_time += end_time - start_time
    return total_time / iterations

# 运行所有性能测试
def run_performance_tests():
    """运行所有性能测试
    
    Returns:
        tuple: (测试结果字典, 错误信息列表)
    """
    test_data = generate_test_data()
    results = {}
    errors = []
    error_counter = 1
    
    # 测试函数列表
    test_functions = [
        ('e2e_list', e2e_list),
        ('e2e_str', e2e_str),
        ('e2e_int', e2e_int),
        ('e2e_float', e2e_float),
        ('e2e_dict', e2e_dict),
        ('e2e_set', e2e_set),
        ('e2e_tuple', e2e_tuple),
    ]
    
    # 运行每种类型的测试
    for data_name, data_value in test_data.items():
        data_results = {}
        for func_name, func in test_functions:
            try:
                avg_time = batch_benchmark(func, data_value)
                data_results[func_name] = avg_time
            except Exception as e:
                # 记录错误信息
                error_info = {
                    'number': error_counter,
                    'data_type': data_name,
                    'function': func_name,
                    'error': str(e)
                }
                errors.append(error_info)
                
                # 在结果中标记为SKIP(N)
                data_results[func_name] = f'SKIP({error_counter})'
                error_counter += 1
        results[data_name] = data_results
    
    return results, errors

# 打印测试结果
def print_performance_results(results, errors=None):
    """打印性能测试结果
    
    Args:
        results: 测试结果字典
        errors: 错误信息列表
    """
    print("\n性能测试结果 (平均执行时间，单位：秒)")
    print("-" * 80)
    
    # 打印表头
    headers = ['数据类型'] + [func_name for func_name, _ in [
        ('e2e_list', e2e_list),
        ('e2e_str', e2e_str),
        ('e2e_int', e2e_int),
        ('e2e_float', e2e_float),
        ('e2e_dict', e2e_dict),
        ('e2e_set', e2e_set),
        ('e2e_tuple', e2e_tuple),
    ]]
    print(f"{headers[0]:<15}" + "".join([f"{h:<12}" for h in headers[1:]]))
    print("-" * 80)
    
    # 打印数据
    for data_name, data_results in results.items():
        row = [data_name[:14]]
        for func_name in headers[1:]:
            value = data_results.get(func_name, 'N/A')
            if isinstance(value, float):
                row.append(f"{value:.8f}")
            else:
                row.append(f"{value:<12}")
        print(f"{row[0]:<15}" + "".join([f"{r:<12}" for r in row[1:]]))
    
    print("-" * 80)
    
    # 打印错误信息
    if errors:
        print("\n错误信息详情:")
        print("-" * 80)
        for error in errors:
            print(f"[{error['number']}] {error['data_type']} -> {error['function']}: {error['error']}")
        print("-" * 80)

# 缓存性能测试
def test_cache_performance():
    """测试缓存性能
    
    Returns:
        dict: 缓存性能测试结果
    """
    print("\n缓存性能测试")
    print("-" * 80)
    
    # 测试数据
    test_data = [42, 3.14, True, 'test', [1, 2, 3]]
    results = {}
    
    for data in test_data:
        # 第一次调用（无缓存）
        time1, _ = benchmark(e2e_list, data)
        
        # 第二次调用（有缓存）
        time2, _ = benchmark(e2e_list, data)
        
        # 计算加速比
        speedup = time1 / time2 if time2 > 0 else float('inf')
        results[str(data)] = {
            'first_call': time1,
            'cached_call': time2,
            'speedup': speedup
        }
        
        print(f"数据: {repr(data):<10} 第一次: {time1:.8f}s 缓存后: {time2:.8f}s 加速比: {speedup:.2f}x")
    
    print("-" * 80)
    return results

# 大型数据集测试
def test_large_dataset_performance():
    """测试大型数据集性能
    
    Returns:
        dict: 大型数据集测试结果
    """
    print("\n大型数据集性能测试")
    print("-" * 80)
    
    # 生成大型数据集
    large_list = list(range(10000))
    large_str = 'x' * 10000
    
    test_cases = [
        ('大型列表 (10000元素)', large_list),
        ('大型字符串 (10000字符)', large_str),
    ]
    
    # 仅当numpy可用时添加numpy测试数据
    if numpy_available:
        large_numpy = np.random.rand(1000, 1000)
        test_cases.append(('大型NumPy数组 (1000x1000)', large_numpy))
    
    results = {}
    for name, data in test_cases:
        time_list, _ = benchmark(e2e_list, data)
        time_str, _ = benchmark(e2e_str, data)
        time_dict, _ = benchmark(e2e_dict, data)
        time_tuple, _ = benchmark(e2e_tuple, data)
        
        results[name] = {
            'to_list': time_list,
            'to_str': time_str,
            'to_dict': time_dict,
            'to_tuple': time_tuple
        }
        
        print(f"{name:<40} to_list: {time_list:.6f}s to_str: {time_str:.6f}s to_dict: {time_dict:.6f}s to_tuple: {time_tuple:.6f}s")
    
    print("-" * 80)
    return results

# 主测试函数
if __name__ == '__main__':
    print("开始性能测试...")
    
    # 运行基本性能测试
    basic_results, errors = run_performance_tests()
    print_performance_results(basic_results, errors)
    
    # 运行缓存性能测试
    cache_results = test_cache_performance()
    
    # 运行大型数据集测试
    large_results = test_large_dataset_performance()
    
    print("\n性能测试完成！")
