【U3D性能优化教程——代码篇】之四:开发需要掌握的协程优化&结构体|类的重构

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/iceSony/article/details/83039196

 

本文由@唐三十胖子出品,转载请注明出处。  
文章链接:
https://blog.csdn.net/iceSony/article/details/83039196

 

 

 

 

协程的创建常见问题:

yield return 0;错

yield return null;对

yield return new WaitForSeconds(1f);错

WaitForSeconds delay = new WaiForSeconds(1f);

yield return delay;对

 

实际中写一个全局的

代码如下:

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.Assertions.Comparers;


// Usage:

//    yield return new WaitForEndOfFrame();     =>      yield return Yielders.EndOfFrame;

//    yield return new WaitForFixedUpdate();    =>      yield return Yielders.FixedUpdate;

//    yield return new WaitForSeconds(1.0f);    =>      yield return Yielders.GetWaitForSeconds(1.0f);


// http://forum.unity3d.com/threads/c-coroutine-waitforseconds-garbage-collection-tip.224878/


public static class Yielders

{

    public static bool Enabled = true;


    public static int _internalCounter = 0; // counts how many times the app yields


    // #gulu WARNING:

    //      Code commented below are incorrect in Unity 5.5.0

    //          - float DOES NOT needs customized IEqualityComparer (but enums and structs do)

    //      however all these lines are kept to help later reader to share this knowledge

    //------------------------------------------------------------------

    ///////////////////// obsoleted code begins \\\\\\\\\\\\\\\\\\\\\\\\

    //// dictionary with a key of ValueType will box the value to perform comparison / hash code calculation while scanning the hashtable.

    //// here we implement IEqualityComparer<float> and pass it to your dictionary to avoid that GC

    //class FloatComparer : IEqualityComparer<float>

    //{

    //    bool IEqualityComparer<float>.Equals(float x, float y)

    //    {

    //        return x == y;

    //    }

    //    int IEqualityComparer<float>.GetHashCode(float obj)

    //    {

    //        return obj.GetHashCode();

    //    }

    //}

    //\\\\\\\\\\\\\\\\\\\\\\\\ obsoleted code ends /////////////////////

    //------------------------------------------------------------------


    static WaitForEndOfFrame _endOfFrame = new WaitForEndOfFrame();

    public static WaitForEndOfFrame EndOfFrame

    {

        get { _internalCounter++; return Enabled ? _endOfFrame : new WaitForEndOfFrame(); }

    }


    static WaitForFixedUpdate _fixedUpdate = new WaitForFixedUpdate();

    public static WaitForFixedUpdate FixedUpdate

    {

        get { _internalCounter++; return Enabled ? _fixedUpdate : new WaitForFixedUpdate(); }

    }


    public static WaitForSeconds GetWaitForSeconds(float seconds)

    {

        _internalCounter++;


        if (!Enabled)

            return new WaitForSeconds(seconds);


        WaitForSeconds wfs;

        if (!_waitForSecondsYielders.TryGetValue(seconds, out wfs))

            _waitForSecondsYielders.Add(seconds, wfs = new WaitForSeconds(seconds));

        return wfs;

    }


    public static void ClearWaitForSeconds()

    {

        _waitForSecondsYielders.Clear();

    }


    static Dictionary<float, WaitForSeconds> _waitForSecondsYielders = new Dictionary<float, WaitForSeconds>(100, new FloatComparer());

}

 

重构代码来减小GC的影响

即使我们减小了代码在堆内存上的分配操作,代码也会增加GC的工作量。最常见的增加GC工作量的方式是让其检查它不必检查的对象。struct是值类型的变量,但是如果struct中包含有引用类型的变量,那么GC就必须检测整个struct。如果这样的操作很多,那么GC的工作量就大大增加。在下面的例子中struct包含一个string,那么整个struct都必须在GC中被检查:

public struct ItemData

{

    public string name;

    public int cost;

    public Vector3 position;

}

private ItemData[] itemData;

我们可以将该struct拆分为多个数组的形式,从而减小GC的工作量:

private string[] itemNames;

private int[] itemCosts;

private Vector3[] itemPositions;

同理适用于Class

猜你喜欢

转载自blog.csdn.net/iceSony/article/details/83039196