你好互联网观众。
我在 Unity 文档中看到了一个名为 Asset Loading Metrics 的页面,所以我会写一篇关于我尝试过的文章。

测试时的环境是Unity2021.3.10f1。

AsyncReadManagerMetrics

Unity 引擎使用 AsyncReadManager 在运行时读取大多数文件。

使用 AsyncReadManagerMetrics 类监控运行时资产加载和文件加载性能。此类记录有关由 AsyncReadManager 管理的所有文件读取操作的数据。

如所写,使用 AsyncReadManagerMetrics 类来收集信息。
然而,

在可能的情况下,度量数据包括有关读取操作的上下文信息。此信息包括请求加载的 AssetLoadingSubsystem、AssetName 和 AssetTypeID。如果 AsyncReadManager 无权访问此信息,则这些指标字段的值分别为 Other、Blank 和 0。

如前所述,可能无法获取 AssetName。
可以获取 FileName,但是根据执行环境的不同,可能很难从文件名中推断出资产。
例如,在使用 Editor 和 AssetDatabase 的模式中,FileName 包含 Artifact 文件名。
D:/AsyncReadManagerMetricsSample/Library/Artifacts/44/443c2d06875ad1ccf3009d49738f637a

Editor运行的时候可能测量的机会不多,但是下面是Artifact文件名到Asset文件名的转换过程。

AssetLoadMetrics.cs
using System.Collections.Generic;
using System.IO;
using Unity.IO.LowLevel.Unsafe;

#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Experimental;
#endif

public static class AssetLoadMetrics
{
    private static readonly Dictionary<string, string> _assetByArtifact;

    static AssetLoadMetrics()
    {
#if UNITY_EDITOR
        // Artifact ファイル名を収集
        _assetByArtifact = new();

        var assets = AssetDatabase.GetAllAssetPaths();
        foreach (var asset in assets)
        {
            // Asset の GUID から Artifact ファイル名を収集
            var guidString = AssetDatabase.AssetPathToGUID(asset);
            var artifactKey = new ArtifactKey(new GUID(guidString));
            var artifactID = AssetDatabaseExperimental.LookupArtifact(artifactKey);
            AssetDatabaseExperimental.GetArtifactPaths(artifactID, out var paths);
            foreach (var path in paths)
            {
                var artifactFileName = Path.GetFileName(Path.GetFullPath(path)).ToLower();
                _assetByArtifact[artifactFileName] = asset;
            }
        }
#endif
    }

    public static void StartCollectingMetrics()
    {
#if ENABLE_PROFILER && UNITY_2020_2_OR_NEWER
        AsyncReadManagerMetrics.StartCollectingMetrics();
#endif
    }

    public static void EndCollectingMetrics(StreamWriter writer)
    {
#if ENABLE_PROFILER && UNITY_2020_2_OR_NEWER
        writer.WriteLine("AssetName,FileName,OffsetBytes,SizeBytes,AssetTypeId,CurrentBytesRead,BatchReadCount,IsBatchRead,State,ReadType,PriorityLevel,Subsystem,RequestTimeMicroseconds,TimeInQueueMicroseconds,TotalTimeMicroseconds");

        var metrics = AsyncReadManagerMetrics.GetMetrics(AsyncReadManagerMetrics.Flags.ClearOnRead);
        foreach (var metric in metrics)
        {
            var asset = metric.AssetName;
            // Asset 名が無い場合で Artifact ファイルなら逆引きを試みる
            if (string.IsNullOrWhiteSpace(asset) && metric.FileName.Contains("Artifacts"))
            {
                _assetByArtifact.TryGetValue(Path.GetFileName(metric.FileName).ToLower(), out asset);
            }

            writer.WriteLine($"{asset},{metric.FileName},{metric.OffsetBytes},{metric.SizeBytes},{metric.AssetTypeId},{metric.CurrentBytesRead},{metric.BatchReadCount},{metric.IsBatchRead},{metric.State},{metric.ReadType},{metric.PriorityLevel},{metric.Subsystem},{metric.RequestTimeMicroseconds},{metric.TimeInQueueMicroseconds},{metric.TotalTimeMicroseconds}");
        }

        AsyncReadManagerMetrics.StopCollectingMetrics();
# endif
    }
}

输出结果将是这样的数据字符串。
Assets/Prefabs/PrefabCube.prefab,D:/AsyncReadManagerMetricsSample/Library/Artifacts/44/443c2d06875ad1ccf3009d49738f637a,0,7168,0,7168,0,False,Completed,Sync,PriorityHigh,Other,21600468747.2,60.5999984741211,111.099998474121

* 顺便说一下,Artifact 周围的处理参考了下面博客中的“如何在磁盘上找到导入结果”。

综上所述

在真机上运行或者使用Addressable等的时候,可能需要多设计一点,不知道能不能照原样做性能调优,不过我一般机会不多关心文件访问情况,所以我注意到了一些东西,我感觉到我可以得到它的气氛。

AsyncReadManagerMetrics 似乎具有获取摘要的功能,因此在某些情况下使用它可能会更好。
* 好像有人放了一个包来获取UnityEditor上的实机信息。

感谢您一如既往的支持。


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308626995.html

相关文章:

  • 2021-11-06
  • 2021-12-19
  • 2022-01-03
  • 2021-08-31
  • 2022-02-05
  • 2021-11-22
猜你喜欢
  • 2021-10-17
  • 2022-12-23
  • 2022-03-02
  • 2022-12-23
  • 2021-08-23
  • 2021-07-22
  • 2021-07-31
相关资源
相似解决方案