在C#中重用数组 [英] Reusing Arrays in C#

查看:171
本文介绍了在C#中重用数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在优化一个非常频繁使用字节数组的C#程序,我写了一种回收池的东西来重用必须由GC收集的数组.像这样:

So I'm optimizing a C# program which uses byte arrays very very frequently, I wrote a kind of recycle pool thing to reuse arrays which had to be collected by GC. Like that:

public class ArrayPool<T>
{
    private readonly ConcurrentDictionary<int, ConcurrentBag<T[]>> _pool;

    public ArrayPool()
    {
        _pool = new ConcurrentDictionary<int, ConcurrentBag<T[]>>();
    }

    public ArrayPool(int capacity)
    {
        _pool = new ConcurrentDictionary<int, ConcurrentBag<T[]>>(4, capacity);
        for (var i = 1; i <= capacity; i++)
        {
            _pool.TryAdd(i, new ConcurrentBag<T[]>());
        }
    }

    public T[] Alloc(int capacity)
    {
        if (capacity < 1)
        {
            return null;
        }
        if (_pool.ContainsKey(capacity))
        {
            var subpool = _pool[capacity];
            T[] result;
            if (subpool != null) return subpool.TryTake(out result) ? result : new T[capacity];
            subpool = new ConcurrentBag<T[]>();
            _pool.TryAdd(capacity, subpool);
            _pool[capacity] = subpool;
            return subpool.TryTake(out result) ? result : new T[capacity];
        }
        _pool[capacity] = new ConcurrentBag<T[]>();
        return new T[capacity];
    }

    public void Free(T[] array)
    {
        if (array == null || array.Length < 1)
        {
            return;
        }
        var len = array.Length;
        Array.Clear(array, 0, len);
        var subpool = _pool[len] ?? new ConcurrentBag<T[]>();
        subpool.Add(array);
    }

}

我还编写了一些代码来测试其性能:

and I also wrote some code to test its performance:

const int TestTimes = 100000;
const int PoolCapacity = 1000;
public static ArrayPool<byte> BytePool;
static void Main()
{
    BytePool = = new ArrayPool<byte>(PoolCapacity);
    var watch = Stopwatch.StartNew();
    for (var i = 1; i <= TestTimes; i++)
    {
        var len = (i % PoolCapacity) + 1;
        var array = new byte[len];
    }
    watch.Stop();
    Console.WriteLine("Traditional Method: {0} ms.", watch.ElapsedMilliseconds);
    watch = Stopwatch.StartNew();
    for (var i = 1; i <= TestTimes; i++)
    {
        var len = (i % PoolCapacity) + 1;
        var array = BytePool.Alloc(len);
        BytePool.Free(array);
    }
    watch.Stop();
    Console.WriteLine("New Method: {0} ms.", watch.ElapsedMilliseconds);
    Console.ReadKey();
}

我认为如果程序每次都可以重用内存而不是malloc的话应该会更快,但是事实证明,我的代码比以前慢了大约10倍:

I thought it should be faster if the program could reuse memory instead of malloc them every time, but it turns out that my code is about 10 times slower than before:

传统方法:31 ms. 新方法:283毫秒.

Traditional Method: 31 ms. New Method: 283 ms.

那么,恢复数组是否可以提高C#的性能,这是真的吗? 如果为true,为什么我的代码这么慢?有没有更好的方法可以重用数组?

So is it true that resuing arrays could increase performance in C#? If true, why my code is so slow? Is there better way to reuse arrays?

任何建议将不胜感激.

推荐答案

您应该签出新的 System.Buffers 包.

这篇关于在C#中重用数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆