2016-04-23 17 views
2

List<T>と同様に動作するが、Clear()が呼び出されたときにそのメモリの割り当てを解除しないで、Sizeプロパティをリセットするだけで.NETのList<T>タイプのクラスを.NETで探しています。メモリを保持する再利用可能なリスト

私の目的はメモリプールでこのクラスを使用することです。そのため、メモリを維持したいが、呼び出し側が標準リストであるかのようにクラスを使用させるが、メモリを再割り当てするのを避ける。

このコードが既に存在する場合は、このコードの最適化、テスト、およびデバッグにかかる​​時間を節約できることをお知らせください。

public class ReusableList<T> 
{ 
    #region Static Properties 

    private static long InitialCapacity = 1000000; 
    private static int CapacityIncreaseRate = 10000; 

    #endregion 

    #region Properties 

    public long Size 
    { 
     get 
     { 
      return this._size; 
     } 
     private set 
     { 
      this._size = 0; 
     } 
    } 
    private long _size = 0; 

    private long RealSize 
    { 
     get 
     { 
      return this._realSize; 
     } 
     set 
     { 
      this._realSize = value; 
     } 
    } 
    private long _realSize = 0; 

    private T[] Data 
    { 
     set 
     { 
      this._data = value; 
     } 
     get 
     { 
      return this._data; 
     } 
    } 
    private T[] _data = null; 

    #endregion 

    #region Operators 

    public T this[long index] 
    { 
     get 
     { 
      return this.Data[index]; 
     } 
     set 
     { 
      this.Data[index] = value; 
     } 
    } 

    #endregion 

    #region Public Methods 

    public ReusableList() 
    { 
     this.Rebuild(); 
    } 

    public void Add(T item) 
    { 
     this.Data[this.Size] = item; 

     this._size++; 

     if (this.Size >= this.RealSize) 
     { 
      this.IncreaseSizeOfList(); 
     } 
    } 

    public void Clear() 
    { 
     this.Size = 0; 
    } 

    #endregion 

    #region Private Methods 

    private void Rebuild() 
    { 
     this.Data = null; 

     this.Data = new T[ReusableList<T>.InitialCapacity]; 

     this.Size = 0; 

     this.RealSize = ReusableList<T>.InitialCapacity; 
    } 

    private void IncreaseSizeOfList() 
    { 
     if (this.Size < this.RealSize) 
      return; 

     var newData = new T[this.RealSize + ReusableList<T>.CapacityIncreaseRate]; 

     Array.Copy(this.Data, newData, this.RealSize); 

     this.Data = newData; 

     this.RealSize += ReusableList<T>.CapacityIncreaseRate; 
    } 

    #endregion 
} 
+0

にデフォルトと設定サイズに配列項目を設定することですか? – jdweng

+0

@jdweng何を思い浮かべましたか? – rhughes

+0

「IList 」を必要なセマンティクスで実装してみませんか?具体的なクラスは、特定のメモリ管理に必要なメソッドを持つことができます。 – casperOne

答えて

0

あなたが内部リストのバックアップを保存することができます:ここでは

は、私は、.NETライブラリで見つけることを期待しています何のモックアップです。

public class ReusableList<T> : List<T> 
{ 
    private List<T> backup; 

    public void Clear(bool purge) 
    { 
     if (purge) 
      backup?.Clear(); 
     else 
      backup = this.ToList(); 

     base.Clear(); 
    } 

    public new void Clear() 
    { 
     this.Clear(false); 
    } 
} 
1

私が理解する限り、これはList<T>という既定の動作です。

リストに項目を追加すると、必要に応じて新しいメモリが割り当てられます。アイテムを削除する(またはリストをクリアする)と、メモリを「解放」せず、内部配列のサイズも減少させません。

内部配列を減らす唯一の方法は、Capacityを減らすことです。 自分でsource codeを調べることができます。例えば、ここにClear方法です:あなたが見ることができるように

public void Clear() 
{ 
    if (_size > 0) 
    { 
     Array.Clear(_items, 0, _size); 
     _size = 0; 
    } 
    _version++; 
} 

は、ここだけあなたはLinkedListのを継承を考えたのは0

+1

'Array.Clear'のコメント:'配列の長さの要素を0に設定します(またはオブジェクト配列ではnull)。 'Array.Clear'を呼び出すと、GCが呼び出されたときのメモリが解放されますか? – rhughes

+0

BCLに[IList.Clear'](https://msdn.microsoft.com/en-us/library/system.collections.ilist.clear(v = vs.110).aspx)の実装がいくつかあります多くのもの( 'List 'を含む)には以下が含まれます:['Array.Clear(_array、0、_size); //これを文書化する必要はありませんが、gcが参照を再利用できるように要素をクリアします。]](http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,303 )。 'Array.Clear'は、GCが以前使用していた参照を再利用できるようにします。 – AGB

関連する問題