今天在写一个工具时,写着写着发现执行速度突然变慢。最后发现是string.StartsWith与EndsWith的锅,改为手动比较后,执行时间变成原来的1/5-1/10。代码如下 ,黄色背景是主要部分
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Threading;
using System.Text.RegularExpressions;
using System;
public class XLogicCodeCheck
{
[MenuItem("代码检查/逻辑层代码检查")]
public static void StartLogicCodeCheck()
{
Debug.Log("逻辑层代码检查");
var path = "Assets/Scripts/Logic";
var files = Directory.GetFiles(path, "*.cs", SearchOption.AllDirectories);
var total = 0.0f;
var totalFind = 0;
var errLines = new List<string>(100);
foreach (var item in files)
{
var allines = File.ReadAllLines(item);
if(allines.Length > 0 && allines[0].Trim().StartsWith("//Float_Uncheck"))
{//Float_Uncheck
continue;
}
for (int i = 0; i < allines.Length; ++i)
{
var ltext = allines[i].Trim();
if (CheckLine(allines, i))
{
var info = $"发现有问题代码,文件:{item}, 行:{i + 1}, {ltext}";
EditorUtility.DisplayDialog("逻辑层代码检查", info, "确定");
errLines.Add(info);
totalFind++;
}
}
EditorUtility.DisplayProgressBar("逻辑层代码检查", $"进度:", total++ / files.Length);
}
if (totalFind == 0)
{
EditorUtility.DisplayDialog("逻辑层代码检查", "检查完成,没有发现问题", "确定");
}
else
{
var savePath = "Assets/FloatCheck.txt";
EditorUtility.DisplayDialog("逻辑层代码检查", $"检查完成,共发现{totalFind}处问题,已保存到文件:{savePath}", "确定");
File.WriteAllLines(savePath, errLines);
}
Debug.Log("逻辑层代码检查完成");
}
static string[] rules = new string[] {
@"[\s(]float[\s)]", @"[\s(]double[\s)]", @"\d+\.\d+", //float, double, 浮点数值
@"\sMath\.[a-zA-Z]+\s*\(", @"\sMathf\.[a-zA-Z]+\s*\(", //Math或Mathf相关API
@"new\s+Random\s*\(",@"new\s+System\s*\.\s*Random\s*\(", @"Random\s*\.\s*RandomRange\s*\(", @"Random\s*\.\s*Range\s*\(", @"Random\s*\.\s*ColorHSV\s*\(",//随机数
};
static string[] excludeRules = new string[] { "Math.Max", "Math.Min", "Math.Abs" }; //排除项,不检查这些
private static bool CheckLine(string[] allines, int iline)
{
var codeStr = FilterComment(allines, iline).Trim();
if (codeStr.Length <= 0) return false;
foreach (var item in rules)
{
var matches = Regex.Matches(codeStr, item);
foreach (Match match in matches)
{
var isok = true;
foreach (var exc in excludeRules)
{
if (match.Value.Contains(exc)) isok = false;
}
if (isok) return true;
}
}
return false;
}
//过滤掉注释
private static string FilterComment(string[] allines, int iline)
{
if (InBlockComment(allines, iline)) return "";
var codeStr = allines[iline];
if (codeStr.Contains("Float_Uncheck") || codeStr.StartsWith("//") || codeStr.StartsWith("/*") || codeStr.StartsWith("#region"))
{
return "";
}
//去除行中注释
var cmtIdx = codeStr.IndexOf("//");
if (cmtIdx < 0)
{
cmtIdx = codeStr.IndexOf("/*");
}
if (cmtIdx >= 0)
{
codeStr = codeStr.Substring(0, cmtIdx);
}
return codeStr;
}
//是否在块注释中
private static bool InBlockComment(string[] allines, int iline)
{
for (int i = iline-1; i>=0; --i)
{
var line = allines[i];
var lineLen = line.Length;
if(lineLen >= 2)
{
if (line[lineLen - 2] == '*' && line[lineLen - 1] == '/')
{//line.EndsWith("*/"),这个函数非常低效
return false;
}
else if (line[0] == '/' && line[1] == '*')
{//line.StartsWith("*/"),这个函数非常低效
return true;
}
}
}
return false;
}
}
版权声明:本文为c1sdn19原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。