diff --git a/UnityDependencyAnalyzer/AssetDefine.cs b/UnityDependencyAnalyzer/AssetDefine.cs index fb5fd5a..a4242f9 100644 --- a/UnityDependencyAnalyzer/AssetDefine.cs +++ b/UnityDependencyAnalyzer/AssetDefine.cs @@ -1,4 +1,5 @@ -using MongoDB.Bson.Serialization.Attributes; +using MemoryPack; +using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver; using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; @@ -8,7 +9,8 @@ using System.Text.Json.Serialization; namespace AssetDependencyGraph { [BsonIgnoreExtraElements] - public class AssetIdentify + [MemoryPackable] + public partial class AssetIdentify { public string Path = null!; public string AssetType = null!; @@ -44,7 +46,8 @@ namespace AssetDependencyGraph } [BsonIgnoreExtraElements] - public class AssetNode + [MemoryPackable] + public partial class AssetNode { public AssetIdentify Self=null!; public string AssetType=null!; diff --git a/UnityDependencyAnalyzer/DependencyAnalysis.cs b/UnityDependencyAnalyzer/DependencyAnalysis.cs index 8713e33..4dd7479 100644 --- a/UnityDependencyAnalyzer/DependencyAnalysis.cs +++ b/UnityDependencyAnalyzer/DependencyAnalysis.cs @@ -1,4 +1,5 @@ -using MongoDB.Bson.Serialization.Attributes; +using MemoryPack; +using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Options; using System; using System.Collections.Concurrent; @@ -239,7 +240,7 @@ namespace AssetDependencyGraph [BsonDictionaryOptions(Representation = DictionaryRepresentation.ArrayOfArrays)] private ConcurrentDictionary assetIdentify2AssetNodeDic = new(); private ConcurrentDictionary path2Id = new(); - private List<(string path, bool isDir)> allPath = new(); + private ConcurrentBag<(string path, bool isDir)> allPath = new(); private UnityLmdb unityLmdb; private static Regex isGuid = new Regex("^[\\da-f]{32}$"); @@ -335,19 +336,19 @@ namespace AssetDependencyGraph unityLmdb.ResolveGuidPath(); } - public void AnalyzeMainProcess(string rootFolder, int processCnt = 8) + public async ValueTask AnalyzeMainProcess(string projectPath, string rootFolder, int processCnt = 8) { Stopwatch sw = Stopwatch.StartNew(); sw.Start(); - Utils.TraverseDirectory(rootFolder, Visivt, -1); + Utils.TraverseDirectoryParallel(rootFolder, Visivt); sw.Stop(); Console.WriteLine($"遍历目录耗时:{sw.ElapsedMilliseconds / 1000f}s"); sw.Restart(); var itemCnt = allPath.Count / processCnt; List subProcessArgs = new(); - List resultJsonPaths = new(); - var projectPath = Environment.GetCommandLineArgs()[1]; + List resultPaths = new(); + var allPathArray = allPath.ToArray(); for (int i = 0; i < processCnt; i++) { int r = (itemCnt * (i + 1)); @@ -355,12 +356,12 @@ namespace AssetDependencyGraph { r = allPath.Count; } - - var s = JsonSerializer.Serialize(allPath[(i * itemCnt)..r], options); + + var s = JsonSerializer.Serialize(allPathArray[(i * itemCnt)..r], options); var jsonPath = Path.Combine(Path.GetTempPath(), $"path{i}.json"); - var resulJsonPath = Path.Combine(Path.GetTempPath(), $"result{i}.json"); - resultJsonPaths.Add(resulJsonPath); - subProcessArgs.Add($"-reference {projectPath} SubProcess {jsonPath} {resulJsonPath}"); + var resulPath = Path.Combine(Path.GetTempPath(), $"result{i}.bin"); + resultPaths.Add(resulPath); + subProcessArgs.Add($"-reference {projectPath} SubProcess {jsonPath} {resulPath}"); File.WriteAllText(jsonPath, s); } @@ -400,10 +401,10 @@ namespace AssetDependencyGraph Task.WaitAll(subProcessTask); List>> subProcessResults = new(); - foreach (var item in resultJsonPaths) + foreach (var item in resultPaths) { - var s = File.ReadAllText(item); - subProcessResults.Add(JsonSerializer.Deserialize>>(s, options)!); + var s = File.ReadAllBytes(item); + subProcessResults.Add(MemoryPackSerializer.Deserialize>>(s.AsSpan())!); } sw.Stop(); Console.WriteLine($"分析引用耗时:{sw.ElapsedMilliseconds / 1000f}s"); @@ -418,14 +419,10 @@ namespace AssetDependencyGraph item.Value.DependentSet = item.Value.Dependent.ToHashSet(); } - string js = JsonSerializer.Serialize(assetIdentify2AssetNodeDic, options: new() - { - IncludeFields = true, - Converters = { new AssetIdentifyJsonConverter(), new AssetNodeJsonConverter() } - }); - - - File.WriteAllText(Path.Combine(UnityLmdb.ProjPath, "Library", "dependencyGraph.json"), js); + using var wr = File.OpenWrite(Path.Combine(UnityLmdb.ProjPath, "Library", "dependencyGraph.bin")); + await MemoryPackSerializer.SerializeAsync(wr, assetIdentify2AssetNodeDic); + sw.Stop(); + Console.WriteLine($"写入文件耗时:{sw.ElapsedMilliseconds / 1000f}s"); //AssetDependencyGraphDB db = new AssetDependencyGraphDB(Environment.GetCommandLineArgs()[2], Environment.GetCommandLineArgs()[3], Environment.GetCommandLineArgs()[4]); //sw.Restart(); @@ -434,8 +431,8 @@ namespace AssetDependencyGraph //{ // db.Insert(item.Value); //}); - sw.Stop(); - Console.WriteLine($"更新数据库:{sw.ElapsedMilliseconds / 1000f}s"); + //sw.Stop(); + //Console.WriteLine($"更新数据库:{sw.ElapsedMilliseconds / 1000f}s"); } private void ResolveSubProcessResult(Dictionary> subProcessResult) @@ -491,25 +488,26 @@ namespace AssetDependencyGraph }); } - public void AnalyzeSubProcess(string pathFile, string resultFilePath) + public async ValueTask AnalyzeSubProcess(string pathFile, string resultFilePath) { var s = File.ReadAllText(pathFile); - allPath = JsonSerializer.Deserialize>(s, options)!; + var allPath = JsonSerializer.Deserialize>(s, options)!; if (allPath != null) { - foreach (var item in allPath) + for (int i = 0; i < allPath.Count; i++) { + var path = allPath[i]; foreach (var item1 in dependencyAnalysisDic) { - if (item1.Key(item)) + if (item1.Key(path)) { - item1.Value.Analyze(item.path, path2Dependences); + item1.Value.Analyze(path.path, path2Dependences); } } } - var json = JsonSerializer.Serialize(path2Dependences, options); - File.WriteAllText(resultFilePath, json); + using var wr = File.OpenWrite(resultFilePath); + await MemoryPackSerializer.SerializeAsync(wr, path2Dependences); } } diff --git a/UnityDependencyAnalyzer/Libs/UnityFileSystemApi.dll b/UnityDependencyAnalyzer/Libs/UnityFileSystemApi.dll index fa1460d..72e36d2 100644 Binary files a/UnityDependencyAnalyzer/Libs/UnityFileSystemApi.dll and b/UnityDependencyAnalyzer/Libs/UnityFileSystemApi.dll differ diff --git a/UnityDependencyAnalyzer/Program.cs b/UnityDependencyAnalyzer/Program.cs index 5b3e610..3e77a8e 100644 --- a/UnityDependencyAnalyzer/Program.cs +++ b/UnityDependencyAnalyzer/Program.cs @@ -34,14 +34,15 @@ switch (Environment.GetCommandLineArgs()[1]) { UnityLmdb.ProjPath = Environment.GetCommandLineArgs()[2]; Utils.DataPath = Path.Combine(UnityLmdb.ProjPath, "Assets").ToUniversalPath(); - + Console.WriteLine(string.Join(' ', Environment.GetCommandLineArgs())); if (Environment.GetCommandLineArgs().Length > 3 && Environment.GetCommandLineArgs()[3].Equals("SubProcess")) { - new DependencyAnalyzer().AnalyzeSubProcess(Environment.GetCommandLineArgs()[4], Environment.GetCommandLineArgs()[5]); + //System.Diagnostics.Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)0x00FF; + await new DependencyAnalyzer().AnalyzeSubProcess(Environment.GetCommandLineArgs()[4], Environment.GetCommandLineArgs()[5]); } else { - new DependencyAnalyzer().AnalyzeMainProcess(Utils.DataPath, 10); + await new DependencyAnalyzer().AnalyzeMainProcess(UnityLmdb.ProjPath, Utils.DataPath, 10); } break; } diff --git a/UnityDependencyAnalyzer/Properties/launchSettings.json b/UnityDependencyAnalyzer/Properties/launchSettings.json index f56dbae..1678af6 100644 --- a/UnityDependencyAnalyzer/Properties/launchSettings.json +++ b/UnityDependencyAnalyzer/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "UnityDependencyAnalyzer": { "commandName": "Project", - "commandLineArgs": "G:/G_android \" \" \" \" localhost" + "commandLineArgs": "-reference G:/G_android \" \" \" \" localhost" } } } \ No newline at end of file diff --git a/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj b/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj index a60f65a..a67c13d 100644 --- a/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj +++ b/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj @@ -8,6 +8,10 @@ False + + + + @@ -51,4 +55,8 @@ + + + +