在开发中,我们经常会遇到以下场景: 1.对象的大量创建和销毁,比如网口接收数据,进行数据解析。 2.大量对象的创建和销毁,导致性能下降。 3 循环中大量new对象
看到微软帮助中有一个ConcurrentBag的用法,挺不错的
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace ObjectPoolExample
{
public class ObjectPool<T>
{
private readonly ConcurrentBag<T> _objects;
private readonly Func<T> _objectGenerator;
public ObjectPool(Func<T> objectGenerator)
{
_objectGenerator = objectGenerator ?? throw new ArgumentNullException(nameof(objectGenerator));
_objects = new ConcurrentBag<T>();
}
public T Get() => _objects.TryTake(out T item) ? item : _objectGenerator();
public void Return(T item) => _objects.Add(item);
}
class Program
{
static void Main(string[] args)
{
var cts = new CancellationTokenSource();
// Create an opportunity for the user to cancel.
_ = Task.Run(() =>
{
if (char.ToUpperInvariant(Console.ReadKey().KeyChar) == 'C')
{
cts.Cancel();
}
});
var pool = new ObjectPool<ExampleObject>(() => new ExampleObject());
Stopwatch sw = new Stopwatch();
sw.Start();
int nCount = 100000;
// Create a high demand for ExampleObject instance.
for (int i = 0; i < nCount; i++)
{
var example = pool.Get();
try
{
// Console.CursorLeft = 0;
// This is the bottleneck in our application. All threads in this loop
// must serialize their access to the static Console class.
//Console.WriteLine($"{example.GetValue(i):####.####}");
}
finally
{
pool.Return(example);
}
}
sw.Stop();
Console.WriteLine("用时1:" + sw.ElapsedMilliseconds + "");
sw.Start();
for (int i = 0; i < nCount; i++)
{
var example = new ExampleObject();
}
sw.Stop();
Console.WriteLine("用时2:" + sw.ElapsedMilliseconds + "");
}
}
// A toy class that requires some resources to create.
class ExampleObject
{
public int[] Nums { get; set; }
public ExampleObject()
{
Nums = new int[10000];
var rand = new Random();
for (int i = 0; i < Nums.Length; i++)
{
Nums[i] = rand.Next();
}
}
public double GetValue(long i) => Math.Sqrt(Nums[i]);
}
}
对比下时间相差还是比较大的