在 C# 中重用数组

2023-12-09

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

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);
    }

}

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

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 倍:

传统方法:31 毫秒。 新方法:283 毫秒。

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

任何建议将不胜感激。谢谢。


你应该看看新的系统缓冲区包裹。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C# 中重用数组 的相关文章

  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • mysql表中的数据非常大。即使 select 语句也需要很多时间

    我正在开发一个数据库 它是一个相当大的数据库 有 13 亿行和大约 35 列 这是我检查表状态后得到的结果 Name Table Name Engine InnoDB Version 10 Row format Compact Rows 1
  • 如何避免情绪低落?

    我有一个实现状态模式每个状态处理从事件队列获取的事件 根据State因此类有一个纯虚方法void handleEvent const Event 事件继承基础Event类 但每个事件都包含其可以是不同类型的数据 例如 int string
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • 获取没有非标准端口的原始 url (C#)

    第一个问题 环境 MVC C AppHarbor Problem 我正在调用 openid 提供商 并根据域生成绝对回调 url 在我的本地机器上 如果我点击的话 效果很好http localhost 12345 login Request
  • C 预处理器库

    我的任务是开发源分析工具C程序 并且我需要在分析本身之前预处理代码 我想知道什么是最好的图书馆 我需要一些重量轻 便于携带的东西 与其推出自己的 为什么不使用cpp这是的一部分gcc suite http gcc gnu org onlin
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • C# 中的递归自定义配置

    我正在尝试创建一个遵循以下递归结构的自定义配置部分
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐