优化红外制导导弹性能,第一轮,修改分辨率,从 640x480 调整为 256x256;

将 InfraredImageGenerator 的 thermalPattern 数组从 double 改为 float;
This commit is contained in:
Tian jianyong 2025-06-05 10:41:28 +08:00
parent 388718b2b3
commit 7c2e56b7e4
12 changed files with 487 additions and 61 deletions

View File

@ -32,9 +32,6 @@ namespace ThreatSource.Tests.Simulation
private const double TIME_STEP = 0.02; // 时间步长50fps
// 性能统计
private long totalAllocations = 0;
private long totalGCCollections = 0;
private long peakMemoryUsage = 0;
private double totalUpdateTime = 0;
private int updateCount = 0;
@ -167,7 +164,14 @@ namespace ThreatSource.Tests.Simulation
};
// 随机选择导弹类型
string[] missileTypes = { "lsgm_001", "itg_001", "mmw_001", "tsm_001" };
//string[] missileTypes = { "lsgm_001", "lbr_001", "irc_001", "itg_001", "mmw_001", "tsm_001" };
//string[] missileTypes = ["lsgm_001"];
//string[] missileTypes = ["lbr_001"];
//string[] missileTypes = ["irc_001"];
string[] missileTypes = ["itg_001"];
//string[] missileTypes = ["mmw_001"];
//string[] missileTypes = ["tsm_001"];
string missileType = missileTypes[Random.Shared.Next(missileTypes.Length)];
var missile = factory.CreateMissile(missileId, missileType, targetId, motionParams);

View File

@ -28,8 +28,8 @@ UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度)
MaxDetectionRange = 1000.0 # 最大探测距离 (米), 默认为1000.0
SearchFieldOfView = 12.0 # 搜索视场角 (度), 默认为12.0度
TrackFieldOfView = 6.0 # 跟踪视场角 (度), 默认为3.0度
ImageWidth = 640 # 图像宽度 (像素)
ImageHeight = 480 # 图像高度 (像素)
ImageWidth = 256 # 图像宽度 (像素)
ImageHeight = 256 # 图像高度 (像素)
BackgroundIntensity = 1.0e-4 # 背景辐射强度 (瓦特/球面度), 默认为1e-4
SearchRecognitionProbability = 0.6 # 搜索模式目标识别概率阈值
TrackRecognitionProbability = 0.8 # 跟踪模式目标识别概率阈值

View File

@ -0,0 +1,46 @@
# 红箭-10 (HJ-10) 导弹配置
Type = "LaserBeamRiderGuidance" # 导弹类型
[Name]
Zh = "红箭-10"
En = "HJ-10"
[Properties]
Type = "LaserBeamRiderGuidance" # 属性中的类型
MaxSpeed = 300.0 # 最大速度 (米/秒)
MaxFlightTime = 60.0 # 最大飞行时间 (秒)
MaxFlightDistance = 5000.0 # 最大飞行距离 (米)
MaxAcceleration = 100.0 # 最大加速度 (米/秒^2)
ProportionalNavigationCoefficient = 3.0 # 比例导引系数
LaunchAcceleration = 100.0 # 发射加速度 (米/秒^2)
MaxEngineBurnTime = 3.0 # 最大发动机燃烧时间 (秒)
CruiseTime = 0.0 # 巡航时间 (秒)
Mass = 24.5 # 质量 (千克)
ExplosionRadius = 5.0 # 爆炸半径 (米)
HitProbability = 0.9 # 命中概率
SelfDestructHeight = 0.0 # 自毁高度 (米)
CruiseAttackAngle = 5.0 # 巡航阶段攻角 (度)
GuidanceSeekingAngle = 0.0 # 制导阶段导引头下视角 (度)
InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度)
UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度)
[LaserBeamRiderGuidanceConfig] # 激光驾束制导配置
MinDetectablePower = 1.0e-10 # 最小可探测功率 (瓦特)
DetectorDiameter = 0.03 # 探测器直径 (米)
ControlFieldDiameter = 20.0 # 控制视场直径 (米, 通常指在某一距离上的光斑直径)
ProportionalGain = 30.0 # 比例增益
IntegralGain = 0.05 # 积分增益
DerivativeGain = 10.0 # 微分增益
NonlinearGain = 0.3 # 非线性增益
MaxGuidanceAcceleration = 50.0 # 最大制导加速度 (米/秒^2)
LowPassFilterCoefficient = 0.2 # 低通滤波器系数
Wavelength = 1.06 # 工作波长 (微米)
JammingResistanceThreshold = 1.0e-5 # 干扰抗性阈值 (瓦特)
[LaserBeamRiderGuidanceConfig.LaserCodeConfig] # 激光编码配置
IsCodeEnabled = true # 是否启用编码
IsCodeMatchRequired = true # 是否要求编码匹配
[LaserBeamRiderGuidanceConfig.LaserCodeConfig.Code]
CodeType = "PRF" # 编码类型
CodeValue = 1010 # 编码值

View File

@ -56,7 +56,7 @@ namespace ThreatSource.Equipment
/// 获取当前的温度分布矩阵
/// </summary>
/// <returns>当前状态下的温度分布矩阵</returns>
public double[,] GetCurrentThermalPattern()
public float[,] GetCurrentThermalPattern()
{
// 根据当前速度判断是否在运动
bool isMoving = KState.Velocity.Magnitude() > 0.1; // 速度大于0.1米/秒认为在运动

View File

@ -387,8 +387,8 @@ namespace ThreatSource.Equipment
SetDefaultValues();
Type = EquipmentType.Tank; // 默认类型为坦克
ThermalPattern = new ThermalPattern(
new double[ThermalPattern.GRID_SIZE, ThermalPattern.GRID_SIZE],
new double[ThermalPattern.GRID_SIZE, ThermalPattern.GRID_SIZE]
new float[ThermalPattern.GRID_SIZE, ThermalPattern.GRID_SIZE],
new float[ThermalPattern.GRID_SIZE, ThermalPattern.GRID_SIZE]
);
RcsPattern = new RcsPattern();
InitializeTypeSpecificProperties();

View File

@ -22,6 +22,6 @@ namespace ThreatSource.Equipment
/// 返回3x3矩阵表示目标侧视图的温度分布
/// 根据目标的运动状态返回静止或运动时的温度分布
/// </remarks>
double[,] GetCurrentThermalPattern();
float[,] GetCurrentThermalPattern();
}
}

View File

@ -18,17 +18,17 @@ namespace ThreatSource.Equipment
/// <summary>
/// 静止状态下的温度分布源数据 (供Tomlyn使用)
/// </summary>
public List<List<double>> StaticPatternSource { get; set; }
public List<List<float>> StaticPatternSource { get; set; }
/// <summary>
/// 运动状态下的温度分布源数据 (供Tomlyn使用)
/// </summary>
public List<List<double>> MovingPatternSource { get; set; }
public List<List<float>> MovingPatternSource { get; set; }
/// <summary>
/// 静止状态下的温度分布(摄氏度)
/// </summary>
public double[,] StaticPattern
public float[,] StaticPattern
{
get { return ConvertSourceToGrid(StaticPatternSource, nameof(StaticPatternSource)); }
}
@ -36,7 +36,7 @@ namespace ThreatSource.Equipment
/// <summary>
/// 运动状态下的温度分布(摄氏度)
/// </summary>
public double[,] MovingPattern
public float[,] MovingPattern
{
get { return ConvertSourceToGrid(MovingPatternSource, nameof(MovingPatternSource)); }
}
@ -47,16 +47,16 @@ namespace ThreatSource.Equipment
public ThermalPattern()
{
// 初始化为空列表以便即使TOML中缺少这些字段属性也不会是null从而简化访问逻辑
StaticPatternSource = new List<List<double>>();
MovingPatternSource = new List<List<double>>();
StaticPatternSource = [];
MovingPatternSource = [];
}
/// <summary>
/// 初始化温度分布模式 (通过 double[,] 数组)
/// 初始化温度分布模式 (通过 float[,] 数组)
/// </summary>
public ThermalPattern(double[,] staticPattern, double[,] movingPattern)
public ThermalPattern(float[,] staticPattern, float[,] movingPattern)
{
// 将输入的 double[,] 转换为 List<List<double>> 并存储
// 将输入的 float[,] 转换为 List<List<float>> 并存储
StaticPatternSource = ConvertGridToSource(staticPattern, nameof(staticPattern));
MovingPatternSource = ConvertGridToSource(movingPattern, nameof(movingPattern));
}
@ -65,7 +65,7 @@ namespace ThreatSource.Equipment
/// 获取指定状态下的温度分布
/// </summary>
/// <param name="isMoving">目标是否在运动</param>
public double[,] GetPattern(bool isMoving)
public float[,] GetPattern(bool isMoving)
{
return isMoving ? MovingPattern : StaticPattern;
}
@ -74,52 +74,52 @@ namespace ThreatSource.Equipment
/// 计算温度梯度特征
/// </summary>
/// <param name="isMoving">目标是否在运动</param>
public double CalculateGradientFeature(bool isMoving)
public float CalculateGradientFeature(bool isMoving)
{
var pattern = GetPattern(isMoving);
// 计算发动机区域(右侧)平均温度
double engineTemp = (pattern[1, 2] + pattern[2, 2]) / 2.0;
float engineTemp = (pattern[1, 2] + pattern[2, 2]) / 2.0f;
// 计算前部区域(左侧)平均温度
double frontTemp = (pattern[1, 0] + pattern[2, 0]) / 2.0;
float frontTemp = (pattern[1, 0] + pattern[2, 0]) / 2.0f;
// 计算中部区域平均温度
double middleTemp = pattern[1, 1];
float middleTemp = pattern[1, 1];
// 计算上部区域平均温度
double topTemp = pattern[0, 1];
float topTemp = pattern[0, 1];
// 计算整体平均温度
double avgTemp = 0;
float avgTemp = 0;
for (int i = 0; i < GRID_SIZE; i++)
for (int j = 0; j < GRID_SIZE; j++)
avgTemp += pattern[i, j];
avgTemp /= (GRID_SIZE * GRID_SIZE);
// 1. 发动机区域温度特征(相对于平均温度的比值)
double engineFeature = engineTemp / (avgTemp + 0.1);
float engineFeature = engineTemp / (avgTemp + 0.1f);
// 2. 前后温度梯度(考虑相对差异)
double frontBackGradient = (engineTemp - frontTemp) / (avgTemp + 0.1);
float frontBackGradient = (engineTemp - frontTemp) / (avgTemp + 0.1f);
// 3. 垂直温度梯度(发动机区域与上部的温度差异)
double verticalGradient = (engineTemp - topTemp) / (avgTemp + 0.1);
float verticalGradient = (engineTemp - topTemp) / (avgTemp + 0.1f);
// 4. 温度集中度(发动机区域相对于中部的温度差异)
double concentrationGradient = (engineTemp - middleTemp) / (avgTemp + 0.1);
float concentrationGradient = (engineTemp - middleTemp) / (avgTemp + 0.1f);
// 坦克特征权重
double engineWeight = 0.4; // 发动机温度特征权重
double frontBackWeight = 0.35; // 前后温度梯度权重
double verticalWeight = 0.15; // 垂直温度梯度权重
double concentrationWeight = 0.1; // 温度集中度权重
float engineWeight = 0.4f; // 发动机温度特征权重
float frontBackWeight = 0.35f; // 前后温度梯度权重
float verticalWeight = 0.15f; // 垂直温度梯度权重
float concentrationWeight = 0.1f; // 温度集中度权重
// 归一化并限制各个特征值
engineFeature = Math.Min(engineFeature, 1.5) / 1.5;
frontBackGradient = Math.Min(Math.Max(frontBackGradient, 0), 1.0);
verticalGradient = Math.Min(Math.Max(verticalGradient, 0), 1.0);
concentrationGradient = Math.Min(Math.Max(concentrationGradient, 0), 1.0);
engineFeature = Math.Min(engineFeature, 1.5f) / 1.5f;
frontBackGradient = Math.Min(Math.Max(frontBackGradient, 0), 1.0f);
verticalGradient = Math.Min(Math.Max(verticalGradient, 0), 1.0f);
concentrationGradient = Math.Min(Math.Max(concentrationGradient, 0), 1.0f);
// 计算最终得分
return engineFeature * engineWeight +
@ -128,8 +128,8 @@ namespace ThreatSource.Equipment
concentrationGradient * concentrationWeight;
}
// 辅助方法:将 List<List<double>> 转换为 double[,]
private double[,] ConvertSourceToGrid(List<List<double>> source, string sourceNameForErrorMessage)
// 辅助方法:将 List<List<float>> 转换为 float[,]
private static float[,] ConvertSourceToGrid(List<List<float>> source, string sourceNameForErrorMessage)
{
if (source == null)
{
@ -141,7 +141,7 @@ namespace ThreatSource.Equipment
throw new InvalidOperationException($"ThermalPattern source data ('{sourceNameForErrorMessage}') must have {GRID_SIZE} rows, but found {source.Count}.");
}
var grid = new double[GRID_SIZE, GRID_SIZE];
var grid = new float[GRID_SIZE, GRID_SIZE];
for (int i = 0; i < GRID_SIZE; i++)
{
if (source[i] == null || source[i].Count != GRID_SIZE)
@ -156,8 +156,8 @@ namespace ThreatSource.Equipment
return grid;
}
// 辅助方法:将 double[,] 转换为 List<List<double>>
private List<List<double>> ConvertGridToSource(double[,] grid, string gridNameForErrorMessage)
// 辅助方法:将 float[,] 转换为 List<List<float>>
private static List<List<float>> ConvertGridToSource(float[,] grid, string gridNameForErrorMessage)
{
if (grid == null)
{
@ -168,10 +168,10 @@ namespace ThreatSource.Equipment
throw new ArgumentException($"Input grid ('{gridNameForErrorMessage}') for ThermalPattern must be {GRID_SIZE}x{GRID_SIZE}.", gridNameForErrorMessage);
}
var source = new List<List<double>>(GRID_SIZE);
var source = new List<List<float>>(GRID_SIZE);
for(int i=0; i < GRID_SIZE; i++)
{
var row = new List<double>(GRID_SIZE);
var row = new List<float>(GRID_SIZE);
for(int j=0; j < GRID_SIZE; j++)
{
row.Add(grid[i,j]);

View File

@ -55,9 +55,9 @@ namespace ThreatSource.Guidance
private const double SMOKE_TEMPERATURE_FACTOR = 1e-11;
/// <summary>
/// 目标温度(K)转换为强度(W/sr)的比例因子 (基于简化 T^4) - **需要调整**
/// 目标温度(K)转换为强度(W/sr)的比例因子 (基于简化 T^4)
/// </summary>
private const double TEMPERATURE_TO_INTENSITY_FACTOR = 1e-6; // Initial guess 1e-11, changed to 1e-7, now 1e-6
private const double TEMPERATURE_TO_INTENSITY_FACTOR = 1e-6;
private const double KELVIN_OFFSET = 273.15;
// 视线坐标系
@ -73,12 +73,7 @@ namespace ThreatSource.Guidance
/// <param name="fieldOfView">视场角</param>
/// <param name="backgroundIntensity">背景辐射强度单位W/sr典型地表背景约0.01-0.1 W/sr</param>
/// <param name="wavelength">红外波长单位微米默认为3.0(中波红外)</param>
public InfraredImageGenerator(
int imageWidth = 640,
int imageHeight = 512,
double fieldOfView = Math.PI / 18,
double backgroundIntensity = 0.01,
double wavelength = 3.0)
public InfraredImageGenerator(int imageWidth, int imageHeight, double fieldOfView, double backgroundIntensity, double wavelength)
{
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
@ -385,10 +380,8 @@ namespace ThreatSource.Guidance
double distance,
double transmittance)
{
// --- 开始: 使用 ThermalPattern 重构 ---
// 获取目标当前的 3x3 热成像模式 (摄氏度)
double[,] thermalPattern = target.GetCurrentThermalPattern();
float[,] thermalPattern = target.GetCurrentThermalPattern();
if (thermalPattern == null)
{
Trace.TraceError($"警告: 目标 {target.Id} 未提供 ThermalPattern无法生成基于模式的强度。");

View File

@ -3,9 +3,6 @@ using ThreatSource.Equipment;
using ThreatSource.Utils;
using ThreatSource.Jammer;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System;
namespace ThreatSource.Guidance
{

View File

@ -491,7 +491,7 @@ namespace ThreatSource.Simulation
/// <summary>
/// 最大探测距离(米)
/// </summary>
public double MaxDetectionRange { get; set; } = 1000; // 默认1公里
public double MaxDetectionRange { get; set; } = 2000; // 默认1公里
/// <summary>
/// 搜索模式视场角,单位:度
@ -506,7 +506,7 @@ namespace ThreatSource.Simulation
/// <summary>
/// 图像宽度,单位:像素
/// </summary>
public int ImageWidth { get; set; } = 640;
public int ImageWidth { get; set; } = 512;
/// <summary>
/// 图像高度,单位:像素

View File

@ -0,0 +1,149 @@
# 性能测试记录
## 测试命令
```bash
dotnet test --configuration Release --filter "RunPerformanceTest" --verbosity detailed --logger "console;verbosity=detailed"
```
## 红外成像制导导弹测试记录
### 初始状态
时间2025-06-05 10:00:00
=== 详细性能测试结果 ===
【基本统计】
测试时长: 30.0 秒
总更新次数: 1391
平均FPS: 46.4
平均帧时间: 3.87 ms
【帧时间分析】
最小帧时间: 0.00 ms
最大帧时间: 69.80 ms
95%分位数: 23.20 ms
99%分位数: 32.41 ms
【内存使用分析】
起始内存: 2.89 MB
结束内存: 9.71 MB
峰值内存: 11.77 MB
内存增长: 6.82 MB
平均内存增长率: 0.23 MB/s
【垃圾回收分析】
Gen0 GC次数: 1008 (33.6 次/秒)
Gen1 GC次数: 952 (31.7 次/秒)
Gen2 GC次数: 952 (31.7 次/秒)
总GC次数: 2912
【性能评级】
帧时间表现: 优秀 ✅
内存管理: 优秀 ✅
GC频率: 较差 ❌
### 第一次优化
时间2025-06-05 10:15:00
- 优化内容:将图像分辨率,从 640x480 调整为 256x256
- 优化效果:
- Gen0、Gen1 GC次数减少 50%Gen2 GC次数减少 80%,帧时间波动减小
- 平均帧时间从 3.87 ms 降低到 1.55 ms最大帧时间从 69.80 ms 降低到 27.98 ms
- 优化结论:
- 图像分辨率降低,各指标基本降低 50%以上,但仍然不够理想,需要进一步优化
=== 详细性能测试结果 ===
【基本统计】
测试时长: 30.0 秒
总更新次数: 1420
平均FPS: 47.3
平均帧时间: 1.55 ms
【帧时间分析】
最小帧时间: 0.00 ms
最大帧时间: 27.98 ms
95%分位数: 7.37 ms
99%分位数: 9.54 ms
【内存使用分析】
起始内存: 1.76 MB
结束内存: 7.65 MB
峰值内存: 11.91 MB
内存增长: 5.89 MB
平均内存增长率: 0.20 MB/s
【垃圾回收分析】
Gen0 GC次数: 530 (17.7 次/秒)
Gen1 GC次数: 528 (17.6 次/秒)
Gen2 GC次数: 188 (6.3 次/秒)
总GC次数: 1246
【性能评级】
帧时间表现: 优秀 ✅
内存管理: 优秀 ✅
GC频率: 较差 ❌
【潜在问题分析】
⚠️ Gen0 GC频率过高存在内存分配风暴
⚠️ 存在显著的帧时间波动GC暂停可能较严重
### 第二次优化
时间2025-06-05 10:30:00
- 优化内容:
- 将 InfraredImageGenerator 的 thermalPattern 数组从 double 改为 float
- 优化效果:
- 几乎没有效果
=== 详细性能测试结果 ===
【基本统计】
测试时长: 30.0 秒
总更新次数: 1419
平均FPS: 47.3
平均帧时间: 1.73 ms
【帧时间分析】
最小帧时间: 0.00 ms
最大帧时间: 23.38 ms
95%分位数: 8.30 ms
99%分位数: 10.22 ms
【内存使用分析】
起始内存: 2.90 MB
结束内存: 7.39 MB
峰值内存: 13.26 MB
内存增长: 4.49 MB
平均内存增长率: 0.15 MB/s
【垃圾回收分析】
Gen0 GC次数: 531 (17.7 次/秒)
Gen1 GC次数: 528 (17.6 次/秒)
Gen2 GC次数: 198 (6.6 次/秒)
总GC次数: 1257
【性能评级】
帧时间表现: 优秀 ✅
内存管理: 优秀 ✅
GC频率: 较差 ❌
【潜在问题分析】
⚠️ Gen0 GC频率过高存在内存分配风暴
⚠️ 存在显著的帧时间波动GC暂停可能较严重
### 第三次优化
时间2025-06-05 10:45:00
- 优化内容:
- 将 InfraredImage 的 Intensity 数组从 double 改为 float
- 优化效果:
- 几乎没有效果

View File

@ -0,0 +1,237 @@
# 性能测试记录
## 测试命令
```bash
dotnet test --configuration Release --filter "RunPerformanceTest" --verbosity detailed --logger "console;verbosity=detailed"
```
## 测试记录
### 2025-06-05 10:00:00
#### 激光半主动导弹
=== 详细性能测试结果 ===
【基本统计】
测试时长: 30.0 秒
总更新次数: 1431
平均FPS: 47.7
平均帧时间: 0.04 ms
【帧时间分析】
最小帧时间: 0.00 ms
最大帧时间: 4.56 ms
95%分位数: 0.09 ms
99%分位数: 0.24 ms
【内存使用分析】
起始内存: 2.90 MB
结束内存: 3.91 MB
峰值内存: 3.91 MB
内存增长: 1.01 MB
平均内存增长率: 0.03 MB/s
【垃圾回收分析】
Gen0 GC次数: 0 (0.0 次/秒)
Gen1 GC次数: 0 (0.0 次/秒)
Gen2 GC次数: 0 (0.0 次/秒)
总GC次数: 0
【性能评级】
帧时间表现: 优秀 ✅
内存管理: 优秀 ✅
GC频率: 优秀 ✅
【潜在问题分析】
⚠️ 存在显著的帧时间波动GC暂停可能较严重
#### 激光驾束制导导弹
=== 详细性能测试结果 ===
【基本统计】
测试时长: 30.0 秒
总更新次数: 1432
平均FPS: 47.7
平均帧时间: 0.03 ms
【帧时间分析】
最小帧时间: 0.00 ms
最大帧时间: 2.79 ms
95%分位数: 0.08 ms
99%分位数: 0.14 ms
【内存使用分析】
起始内存: 2.91 MB
结束内存: 3.95 MB
峰值内存: 3.95 MB
内存增长: 1.04 MB
平均内存增长率: 0.03 MB/s
【垃圾回收分析】
Gen0 GC次数: 0 (0.0 次/秒)
Gen1 GC次数: 0 (0.0 次/秒)
Gen2 GC次数: 0 (0.0 次/秒)
总GC次数: 0
【性能评级】
帧时间表现: 优秀 ✅
内存管理: 优秀 ✅
GC频率: 优秀 ✅
【潜在问题分析】
⚠️ 存在显著的帧时间波动GC暂停可能较严重
#### 红外指令制导导弹
=== 详细性能测试结果 ===
【基本统计】
测试时长: 30.0 秒
总更新次数: 1430
平均FPS: 47.6
平均帧时间: 0.05 ms
【帧时间分析】
最小帧时间: 0.00 ms
最大帧时间: 3.79 ms
95%分位数: 0.10 ms
99%分位数: 0.30 ms
【内存使用分析】
起始内存: 2.89 MB
结束内存: 3.99 MB
峰值内存: 3.99 MB
内存增长: 1.10 MB
平均内存增长率: 0.04 MB/s
【垃圾回收分析】
Gen0 GC次数: 0 (0.0 次/秒)
Gen1 GC次数: 0 (0.0 次/秒)
Gen2 GC次数: 0 (0.0 次/秒)
总GC次数: 0
【性能评级】
帧时间表现: 优秀 ✅
内存管理: 优秀 ✅
GC频率: 优秀 ✅
【潜在问题分析】
⚠️ 存在显著的帧时间波动GC暂停可能较严重
#### 红外成像制导导弹
=== 详细性能测试结果 ===
【基本统计】
测试时长: 30.0 秒
总更新次数: 1391
平均FPS: 46.4
平均帧时间: 3.87 ms
【帧时间分析】
最小帧时间: 0.00 ms
最大帧时间: 69.80 ms
95%分位数: 23.20 ms
99%分位数: 32.41 ms
【内存使用分析】
起始内存: 2.89 MB
结束内存: 9.71 MB
峰值内存: 11.77 MB
内存增长: 6.82 MB
平均内存增长率: 0.23 MB/s
【垃圾回收分析】
Gen0 GC次数: 1008 (33.6 次/秒)
Gen1 GC次数: 952 (31.7 次/秒)
Gen2 GC次数: 952 (31.7 次/秒)
总GC次数: 2912
【性能评级】
帧时间表现: 优秀 ✅
内存管理: 优秀 ✅
GC频率: 较差 ❌
【潜在问题分析】
⚠️ Gen0 GC频率过高存在内存分配风暴
⚠️ 存在显著的帧时间波动GC暂停可能较严重
#### 毫米波制导导弹
=== 详细性能测试结果 ===
【基本统计】
测试时长: 30.0 秒
总更新次数: 1419
平均FPS: 47.3
平均帧时间: 0.76 ms
【帧时间分析】
最小帧时间: 0.00 ms
最大帧时间: 11.79 ms
95%分位数: 3.25 ms
99%分位数: 4.59 ms
【内存使用分析】
起始内存: 2.91 MB
结束内存: 10.98 MB
峰值内存: 11.09 MB
内存增长: 8.07 MB
平均内存增长率: 0.27 MB/s
【垃圾回收分析】
Gen0 GC次数: 21 (0.7 次/秒)
Gen1 GC次数: 1 (0.0 次/秒)
Gen2 GC次数: 0 (0.0 次/秒)
总GC次数: 22
【性能评级】
帧时间表现: 优秀 ✅
内存管理: 优秀 ✅
GC频率: 优秀 ✅
【潜在问题分析】
⚠️ 存在显著的帧时间波动GC暂停可能较严重
#### 末敏弹
=== 详细性能测试结果 ===
【基本统计】
测试时长: 30.0 秒
总更新次数: 1423
平均FPS: 47.4
平均帧时间: 0.16 ms
【帧时间分析】
最小帧时间: 0.01 ms
最大帧时间: 8.46 ms
95%分位数: 0.24 ms
99%分位数: 0.52 ms
【内存使用分析】
起始内存: 1.72 MB
结束内存: 10.16 MB
峰值内存: 10.16 MB
内存增长: 8.44 MB
平均内存增长率: 0.28 MB/s
【垃圾回收分析】
Gen0 GC次数: 1 (0.0 次/秒)
Gen1 GC次数: 0 (0.0 次/秒)
Gen2 GC次数: 0 (0.0 次/秒)
总GC次数: 1
【性能评级】
帧时间表现: 优秀 ✅
内存管理: 优秀 ✅
GC频率: 优秀 ✅
【潜在问题分析】
⚠️ 存在显著的帧时间波动GC暂停可能较严重