So reduzieren Sie die Speicherzuweisung für Datentypen, deren Lebensdauer nicht definiert istC#

Ein Treffpunkt für C#-Programmierer
Guest
 So reduzieren Sie die Speicherzuweisung für Datentypen, deren Lebensdauer nicht definiert ist

Post by Guest »

Ich habe einen Datentyp, dessen Lebensdauer undefiniert ist. Daher ist es eine Klasse. Allerdings wird es sehr oft erstellt, was dazu führt, dass es ständig Speicher belegt. Es hat auch ziemlich viel Gewicht, was es problematisch macht.
Was kann getan werden, um die Anzahl der für diesen Datentyp erforderlichen Zuweisungen zu reduzieren, seine Zuweisungen und Freigaben zu optimieren und GC zu reduzieren? Druck? (Das Erstellen einer Struktur würde nicht funktionieren, da dies ein ständiges Kopieren von Daten erfordern würde und es unmöglich wäre, Daten immer über try-finally aus dem internen Array freizugeben.)

Code: Select all

[Serializable]
public class DamageData
{
[Serializable]
public class DamageDataInternal
{
public float[] values;
public float totalDamage;
public int cachedHashCode;
public bool isHashCodeDirty;
}

private DamageDataInternal _internalData;

public static readonly DamageType[] DamageTypes;

public int Hash => GetHashCode();
public bool IsInit => _internalData != null;

static DamageData()
{
DamageTypes = (DamageType[])Enum.GetValues(typeof(DamageType));
}

~DamageData()
{
DamageDataInternalPool.Shared.Release(_internalData);
_internalData = null;
}

public DamageData()
{
_internalData = DamageDataInternalPool.Shared.Get();
_internalData.totalDamage = 0f;
_internalData.isHashCodeDirty = true;
_internalData.cachedHashCode = 0;
}
}

Code: Select all

using UnityEngine.Pool;
public class DamageDataInternalPool
{
private readonly ObjectPool _pool;

public static DamageDataInternalPool Shared { get; } = new();

public DamageDataInternalPool()
{
_pool = new ObjectPool(
createFunc: () => new DamageData.DamageDataInternal(),
actionOnGet: obj =>
{
obj.totalDamage = default;
obj.cachedHashCode = default;
obj.isHashCodeDirty = default;
obj.values = ArrayPool.Shared.Rent(DamageData.DamageTypes.Length);
for (var i = 0; i < DamageData.DamageTypes.Length; i++)
{
obj.values[i] = 0f;
}
},
actionOnRelease: obj =>
{
ArrayPool.Shared.Return(obj.values);
},
actionOnDestroy: null,
defaultCapacity: 10,
maxSize: 10000
);
}

public DamageData.DamageDataInternal Get()
{
return _pool.Get();
}

public void Release(DamageData.DamageDataInternal obj)
{
_pool.Release(obj);
}
}
Ich habe versucht, die internen Daten in einer separaten Klasse zu kapseln, von denen ich Instanzen über Objektpooling erhalte, sodass die Hauptklasse nur SIZE_OF_LINK + SOME_META_DATA_SIZE wiegen sollte. Allerdings scheint sich dadurch an der Situation überhaupt nichts geändert zu haben und es gibt immer noch viel Zuteilung.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post