Пример #1
0
    // Use this for initialization
    IEnumerator Start()
    {
        yield return(FullUnloadAndGC());

        Time.maximumDeltaTime       = 10;
        Application.targetFrameRate = 1000;

        //计算每帧Overhead
        float baseFrameTime  = 0;
        int   baseFrameCount = 33;

        for (int i = 0; i < baseFrameCount; i++)
        {
            yield return(UtilityOwn.Yield.WaitForEndOfFrame);

            baseFrameTime += Time.deltaTime;
        }
        baseFrameTime /= baseFrameCount;
        Debug.LogFormat("average delta time of {0} frames: {1}", baseFrameCount, baseFrameTime);

        mInitTextureSamples = GetTextureMemorySamples();

        if (testAssetPathList.Count == 0)
        {
            ReloadAssetPath(ref testAssetPathList);
        }

        var    now      = DateTime.Now;
        string fileName = string.Format("AssetProfilingReport_{0:d4}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.csv",
                                        now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);

        mSavePath = Path.Combine(Path.GetDirectoryName(Application.dataPath), fileName);

        mProgress = 0;
        System.Text.StringBuilder builder = new System.Text.StringBuilder();
        StreamWriter sw = new StreamWriter(mSavePath, false, System.Text.Encoding.UTF8);

        ProfilingReport.ExportColomnName(builder, topFrameCount);
        sw.Write(builder.ToString());
        builder.Length = 0;
        for (mProgress = 0; mProgress < testAssetPathList.Count; mProgress++)
        {
            builder.Length = 0;
            yield return(AnalyzeSingleAsset(testAssetPathList[mProgress], baseFrameTime));

            mTempReport.Export(builder);
            sw.Write(builder.ToString());
            sw.Flush();
        }
        sw.Close();
    }
Пример #2
0
    IEnumerator AnalyzeSingleAsset(string assetPath, float baseFrameTime)
    {
        mTempReport      = new ProfilingReport();
        mTempReport.path = assetPath;

        //清除缓存资源
        yield return(FullUnloadAndGC());

        //独立的代码块来声明局部变量,限定作用域
        {
            //加载
            float      t1           = Time.realtimeSinceStartup;
            GameObject targetObject = AssetDatabase.LoadAssetAtPath <GameObject>(assetPath);
            float      t2           = Time.realtimeSinceStartup;
            mTempReport.loadTime = (t2 - t1) * 1000;
            yield return(UtilityOwn.Yield.WaitForEndOfFrame);

            yield return(UtilityOwn.Yield.WaitForEndOfFrame);

            if (targetObject == null)
            {
                Debug.LogError("load asset failed:" + assetPath);
                yield break;
            }

            var objRenderers = targetObject.GetComponentsInChildren <Renderer>(true);
            var objMaterials = new HashSet <Material>();
            foreach (var r in objRenderers)
            {
                foreach (var mat in r.sharedMaterials)
                {
                    objMaterials.Add(mat);
                }
                if (r is MeshRenderer)
                {
                    var mr   = r as MeshRenderer;
                    var mesh = mr.GetComponent <MeshFilter>().sharedMesh;
                    if (mesh)
                    {
                        mTempReport.meshVertexCount   += mesh.vertexCount;
                        mTempReport.meshTriangleCount += mesh.triangles.Length / 3;
                    }
                }
                else if (r is SkinnedMeshRenderer)
                {
                    var smr  = r as SkinnedMeshRenderer;
                    var mesh = smr.sharedMesh;
                    if (mesh)
                    {
                        mTempReport.meshVertexCount   += smr.sharedMesh.vertexCount;
                        mTempReport.meshTriangleCount += smr.sharedMesh.triangles.Length / 3;
                    }
                }
                else if (r is ParticleSystemRenderer)
                {
                    var psr  = r as ParticleSystemRenderer;
                    var mesh = psr.mesh;
                    if (mesh)
                    {
                        mTempReport.meshVertexCount   += mesh.vertexCount;
                        mTempReport.meshTriangleCount += mesh.triangles.Length / 3;
                    }
                }
            }
            mTempReport.rendererCount = objRenderers.Length;
            mTempReport.materialCount = objMaterials.Count;

            mTempReport.particleSystemCount = targetObject.GetComponentsInChildren <ParticleSystem>(true).Length;
            mTempReport.animationCount      = targetObject.GetComponentsInChildren <Animation>(true).Length;
            mTempReport.animatorCount       = targetObject.GetComponentsInChildren <Animator>(true).Length;

            yield return(UtilityOwn.Yield.WaitForEndOfFrame);

            yield return(UtilityOwn.Yield.WaitForEndOfFrame);


            t2 = Time.realtimeSinceStartup;
            //实例化
            var instList = new List <GameObject>();
            for (int i = 0; i < instantiateCountForEach; i++)
            {
                GameObject go = Instantiate(targetObject);
                go.transform.position = Vector3.zero;
                instList.Add(go);
            }
            float t3 = Time.realtimeSinceStartup;
            mTempReport.instTime = (t3 - t2) * 1000f / instantiateCountForEach;

            //渲染
            ParticleSystem[] psOfOneInst = instList[0].GetComponentsInChildren <ParticleSystem>(true);
            yield return(UtilityOwn.Yield.WaitForEndOfFrame);

            yield return(UtilityOwn.Yield.WaitForEndOfFrame);

            yield return(UtilityOwn.Yield.WaitForEndOfFrame);

            float t4 = Time.realtimeSinceStartup;
            mTempReport.frameTimeMin = float.MaxValue;
            mTempReport.frameTimeMax = float.MinValue;
            int          frame         = 0;
            List <float> frameTimeList = new List <float>();
            while (Time.realtimeSinceStartup - t4 < testTimeForEach)
            {
                var dtMs = Time.deltaTime * 1000;
                frame++;
                mTempReport.frameTimeMin = Math.Min(mTempReport.frameTimeMin, dtMs);
                mTempReport.frameTimeMax = Math.Max(mTempReport.frameTimeMax, dtMs);
                frameTimeList.Add(dtMs);
                int particleCount = 0;
                for (int i = 0; i < psOfOneInst.Length; ++i)
                {
                    particleCount += psOfOneInst[i].particleCount;
                }
                if (mTempReport.particleAliveCountMax < particleCount)
                {
                    mTempReport.particleAliveCountMax = particleCount;
                }
                yield return(UtilityOwn.Yield.WaitForEndOfFrame);
            }
            mTempReport.frameTimeMin = mTempReport.frameTimeMin / instantiateCountForEach - baseFrameTime;
            mTempReport.frameTimeMax = mTempReport.frameTimeMax / instantiateCountForEach - baseFrameTime;
            frameTimeList.Sort();
            frameTimeList.Reverse();
            float avg  = 0f;
            int   topX = Math.Min(topFrameCount, frameTimeList.Count);
            for (int i = 0; i < topX; ++i)
            {
                avg += frameTimeList[i];
            }
            mTempReport.frameTimeAvgTopX = avg / topX / instantiateCountForEach - baseFrameTime;
            if (topX < topFrameCount)
            {
                Debug.LogWarning("frame count lower than expectation:" + assetPath);
            }

            //统计纹理信息
            yield return(UtilityOwn.Yield.WaitForEndOfFrame);

            mTempReport.textureInfoDetails = new Dictionary <IntPtr, TextureInfo>();
            var texSamples = GetTextureMemorySamples();
            foreach (var t in texSamples)
            {
                if (mInitTextureSamples.ContainsKey(t.Key) == false)
                {
                    mTempReport.textureInfoDetails.Add(t.Key, t.Value);
                    mTempReport.texMemKBytes += t.Value.Bytes;
                    mTempReport.texMemCount++;
                }
            }

            //清理
            foreach (var obj in instList)
            {
                UnityEngine.Object.DestroyImmediate(obj);
            }
            instList.Clear();
            texSamples.Clear();
        }

        yield return(FullUnloadAndGC());
    }