• C#中设计一个 ListPool 的方案


    1、回顾一下有关List的几个知识点。

        点1: 注意理解 Capacity 与 Count 的不同之处。

        点2: 执行 TrimExcess() 方法可将容量设置为 List 中元素的实际数目。

        点3: List的 Capacity (注意理解与 Count 的不同之处)扩充是以 4 的倍数来扩充的。

        点4: 执行完 Clear() 方法后,Capacity 是不会变化的。

    1 List<int> list = new List<int>();
    2 Console.WriteLine(list.Capacity);   // 0
    3 list.Add(1);
    4 Console.WriteLine(list.Capacity);   // 4

    2、ListPool方案:

      1 using System;
      2 using System.Collections.Generic;
      3 
      4 public interface IListPoolBase
      5 {
      6     void DoClear(int nowSeconds);
      7 }
      8 
      9 public class ListPoolItem<T> : IListPoolBase
     10 {
     11     static int intervalTime = 30;  //清理池子的时间间隔(单位 : 秒)
     12     public List<List<T>> pool;      //用List而不用Stack是因为在回收的时候,当pool达到上限的时候,要替换到 Capacity 最大的那个,用 Stack 无法自主替换
     13     public int lastUsedSeconds;
     14 
     15     public ListPoolItem(int initSize)
     16     {
     17         lastUsedSeconds = (int)(DateTime.Now.Ticks / TimeSpan.TicksPerSecond);
     18         pool = new List<List<T>>(initSize);
     19     }
     20 
     21     //长时间不用,清理一下池子
     22     public void DoClear(int nowSeconds)
     23     {
     24         if (pool.Count > 0)
     25         {
     26             int durationNotUse = nowSeconds - lastUsedSeconds;
     27             if (durationNotUse >= intervalTime)
     28             {
     29                 pool.Clear();
     30             }
     31         }
     32     }
     33 
     34     public void Use()
     35     {
     36         lastUsedSeconds = (int)(DateTime.Now.Ticks / TimeSpan.TicksPerSecond);
     37     }
     38 }
     39 
     40 public static class ListPool<T>
     41 {
     42     public static int maxPoolSize = 4;
     43     static ListPoolItem<T> poolItem;
     44 
     45     static ListPool()
     46     {
     47         poolItem = new ListPoolItem<T>(maxPoolSize);
     48         ListPoolManager.Register(poolItem);
     49     }
     50 
     51     public static List<T> Get()
     52     {
     53         lock (poolItem)
     54         {
     55             poolItem.Use();
     56             List<List<T>> pool = poolItem.pool;
     57             int poolSize = pool.Count;
     58             if (poolSize > 0)
     59             {
     60                 List<T> list = pool[poolSize - 1];
     61                 pool.RemoveAt(poolSize - 1);
     62                 return list;
     63             }
     64             else
     65             {
     66                 return new List<T>();
     67             }
     68         }
     69     }
     70 
     71     public static void Release(ref List<T> list)
     72     {
     73         if (null == list) return;
     74         lock (poolItem)
     75         {
     76             poolItem.Use();
     77             List<List<T>> pool = poolItem.pool;
     78             List<T> _list = list;
     79             list = null;
     80             if (pool.Contains(_list))
     81                 return;
     82             _list.Clear();
     83 
     84             //当_List的开辟的容量过大的时候,需要考虑到无用的容量,之所以加这个判断而不是直接清除,是为了避免反复的开辟空间
     85             if (_list.Capacity >= 4096)
     86             {
     87                 _list.TrimExcess();
     88             }
     89 
     90             int poolSize = pool.Count;
     91             //当pool的容量达到最大的时候,替换掉容量最大的那个
     92             if (poolSize >= maxPoolSize)
     93             {
     94                 int replaceIndex = -1;
     95                 int maxCapacity = _list.Capacity;
     96                 for (int i = 0; i < poolSize; ++i)
     97                 {
     98                     List<T> curList = pool[i];
     99                     if (curList.Capacity > maxCapacity)
    100                     {
    101                         replaceIndex = i;
    102                         maxCapacity = curList.Capacity;
    103                     }
    104                 }
    105 
    106                 if (replaceIndex >= 0)
    107                 {
    108                     pool[replaceIndex] = _list;
    109                 }
    110                 return;
    111             }
    112 
    113             pool.Add(_list);
    114         }
    115     }
    116 }
    117 
    118 //检测ListPool的使用情况
    119 public static class ListPoolManager
    120 {
    121     static int _timerMS;
    122     static int _minTriggerTimeMS = 3000;  //执行检测的时间间隔
    123     static List<IListPoolBase> listPool = new List<IListPoolBase>();
    124 
    125     public static void Register(IListPoolBase poolItem)
    126     {
    127         listPool.Add(poolItem);
    128     }
    129 
    130     //在主线程中做检测
    131     public static void DoTracer(int deltaTimeMS)
    132     {
    133         _timerMS += deltaTimeMS;
    134         //降低执行检测的频率
    135         if (_timerMS < _minTriggerTimeMS)
    136             return;
    137 
    138         _timerMS = 0;
    139 
    140         int nowSeconds = (int)(DateTime.Now.Ticks / TimeSpan.TicksPerSecond);
    141         for (int i = 0; i < listPool.Count; ++i)
    142         {
    143             listPool[i].DoClear(nowSeconds);
    144         }
    145     }
    146 }
  • 相关阅读:
    setTimeout 理解
    Git 使用规范流程
    JavaScript异步编程 ( 一 )
    javaScript模块化一
    javascript 知识点坑
    javaScript闭包
    函数式编程
    JavaScript的68个技巧一
    MySql 隐式转换
    MySQL优化
  • 原文地址:https://www.cnblogs.com/luguoshuai/p/12859369.html
Copyright © 2020-2023  润新知