【学习积累】Queue 与 ConcurrentQueue性能测试

news2025/1/18 16:48:43

        在 C# 中,关于队列(Queue)有两种,一种就是我们普通使用的队列,另一种是线程安全的队列 ConcurrentQueue<T> 。

ConcurrentQueue表示线程安全的先进先出 (FIFO) 集合。https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentqueue-1?view=netstandard-2.1        这两者在数据结构上,都是先进先出(FIFO)的集合,一般情况下我们都是用的 Queue 这种常规队列就能满足需求。当然,在多线程情况下,如果是用 Queue,因为线程不安全,在线程竞争的时候(多线程入队或多线程出队)就会造成异常,此时我们就会用到 ConcurrentQueue。那么这两者性能差异是如何的呢?

        本文将对这两个队列进行一个简单的性能测试,同时讨论一种特殊情况:一个线程入队,一个线程出队时使用 Queue 的情况。

1、单一线程入队+单一线程出队情况

        这里我们讨论多线程的特殊情况:假设队列只有一个线程进行入队,同时,只有一个线程进行出队。那么在这种情况下,我们使用线程不安全队列 Queue 会不会有问题?如果在在 Unity 中,写入、读取有耗时操作,会不会出现异常?

        这里我们的测试用例很简单:

        public static void AddTaskItem()
        {
            System.Random rand = new System.Random();

            for (int i = 0; i < MaxCount; i++)
            {
                TaskItem item = new TaskItem();
                item.Index = i;
                TestQueue.Enqueue(item);
                Thread.Sleep(rand.Next(0, 5));
            }

            Debug.Log("全部数据添加完毕!");
        }


        public class TaskItem
        {
            public int Index;
    
            public void DoSomeWork(){}// 某耗时函数,此处略去
        }

        这里我将 MaxCount 设置为 10000,之后在 Unity 主线程进行 Update:

        public int CurIndex = 0;

        private void Update()
        {
            int updateCount = TestQueue.Count;
            int lastIndex = CurIndex;
            //取出当前队列的所有值,并比对;
            while (testQueue.Count > 0)
            {
                var item = testQueue.Dequeue();
                if (item.Index != CurIndex)
                {
                    Debug.LogError($"取值错误,应该是:{CurIndex},实际是  :{item.Index}");
                }

                item.DoSomeWork();

                CurIndex++;
            }

            Debug.Log($"本次取出队列:{CurIndex - lastIndex} / {updateCount}");
        }

        显然,只要取值错误,即当前取出的值不是在主线程记录的序号(CurIndex),就会抛出错误。不过我进行了多次测试,并没有出现过一次错误,即便是增加了耗时函数,导致每帧取值并不是一开始的值,但仍然不会出现出队入队异常。

        所以我们得出结论:

        在仅有一个线程入队、一个线程出队的情况下,使用队列 Queue 是不会有异常的。

2、性能测试

        这里我们就简单地进行入队出队的性能测试,这里就不贴测试代码了,直接出结论:

        整体来看,ConcurrentQueue 的性能开销都是大于 Queue 的,其中:

        写入耗时:ConcurrentQueue 约为 Queue 的 1.3 倍。

        读取耗时:ConcurrentQueue 约为 Queue 的 6 倍。

        同时,随着队列中的数据增多,ConcurrentQueue 的读取耗时将会显著增加。

        当然,如果队列中数量不是很多,这两者的差别并不算太大,微秒级别的差异在一般情况下可以无视。同时,队列中有上千万个元素的情况在一般游戏中非常少见(一般队列中有个几百个元素就不得了了),所以不用太在意 ConcurrentQueue 带来的额外性能开销。

        同时,本次测试都是单线程的读写,相当于抛弃了 ConcurrentQueue 的优势(多线程安全)来测试,有些许不公。在实际使用时 ConcurrentQueue 一定是在多线程读写的场景,其安全性与性能肯定会显著优于 Queue 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/428035.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【创作赢红包】python学习——【第七弹】

前言 上一篇文章 python学习——【第六弹】中介绍了 python中的字典操作&#xff0c;这篇文章接着学习python中的可变序列 集合 集合 1&#xff1a; 集合是python语言提供的内置数据结构&#xff0c;具有无序性&#xff08;集合中的元素无法通过索引下标访问&#xff0c;并且…

Qt框架概述

Qt框架概述一、什么是Qt二、了解QtCreator三、创建Qt项目*Qt项目框架及文件介绍四、设置窗口属性五、按钮创建按钮方式一按钮属性设置创建按钮方式二六、对象模型一、什么是Qt 概念&#xff1a; Qt是一个基于C的 跨平台的图形用户界面应用程序框架。 常见GUI Qt &#xff1a;…

状态错误 MSB8040,此项目需要缓解了 Spectre 漏洞的库。从 Visual Studio 安装程序(单个组件选项卡)为正在使用的任何工具集和体

“Spectre Mitigation”缓解错误 如果出现“Spectre Mitigation”这种错误&#xff0c;就要了解下PIPE技术&#xff1a;流水线技术&#xff0c;比如3级流水线&#xff0c;避免CPU空闲&#xff0c;不浪费时间&#xff0c;但是前提是没有跳转&#xff0c;指令都是顺序执行的&…

pytorch transforms图像增强

一、前言 在学习自己的项目发现自己有很多基础知识不牢&#xff0c;对于图像处理有点不太清楚&#xff0c;因此写下来作为自己的笔记&#xff0c;主要是我想自己动手写一下每一句代码到底做了什么&#xff0c;而不是单纯的我看了知道了它做了什么&#xff0c;说白了&#xff0c…

【Maven】开发自己的starter依赖

【Maven】开发自己的starter依赖 文章目录【Maven】开发自己的starter依赖1. 准备工作1.1 创建一个项目1.2 修改pom文件1.3 修改项目结构2. 动手实现2.1 创建客户端类2.2 创建配置类2.3 配置路径2.4 下载到本地仓库3. 测试1. 准备工作 1.1 创建一个项目 打开idea&#xff0c;…

BP神经网络原来就是曲线拟合

本站原创文章&#xff0c;转载请说明来自《老饼讲解-BP神经网络》bp.bbbdata.com 在初学BP神经网络的时候&#xff0c;总是非常抽象和难理解 但是&#xff0c;学久了会发现&#xff0c;BP神经网络原来就是曲线拟合&#xff01; 一下子才具体、深入的理解到BP神经网络是什么 本文…

字节,腾讯过来的面试自动化测试就这水平吗?鬼知道经历了什么?

本人12年从业经验&#xff0c;曾就职于美团测试开发框架组&#xff0c;搭建过美团platuo测试框架&#xff0c;thrift测试框架&#xff0c;自动化测试平台&#xff0c;熟悉python3&#xff0c;java&#xff0c;vue&#xff0c;在多家公司从0到1搭建过自动化测试框架&#xff0c;…

linux文件编辑--vi

目录标题vi/vim中三种模式命令模式下的常用命令--光标移动输入模式末行模式vim中常用的操作类型命令行模式下的常用命令--复制、粘贴、删除命令模式下的常用命令--文件内容查找命令模式中的基本操作--撤销编辑及保存退出末行模式中的基本操作--保存文件内容及退出vi编辑器末行模…

GitHub标星15w,如何用Python实现所有算法?

学会了 Python 基础知识&#xff0c;想进阶一下&#xff0c;那就来点算法吧&#xff01;毕竟编程语言只是工具&#xff0c;结构算法才是灵魂。 新手如何入门 Python 算法&#xff1f; 几位印度小哥在 GitHub 上建了一个各种 Python 算法的新手入门大全。从原理到代码&#xf…

[论文阅读RGBD-SOD][2022_TCSVT_MoADNet][轻量化]

MoADNet: Mobile Asymmetric Dual-Stream Networks for Real-Time and Lightweight RGB-D Salient Object Detection paper&#xff1a;https://ieeexplore.ieee.org/abstract/document/9789193 动机 尽管已有许多优秀的RGB-D SOD技术被提出&#xff0c;但它们大多关注性能…

面试篇-从今天开始彻底分清Java内存模型JMM和运行时数据区

“相信很多人会把Java内存模型与Java运行时数据区给搞混淆” Java内存模型和Java运行时数据区是两个不同的概念&#xff0c;很容易让人混淆。下面简单介绍一下它们的区别&#xff1a; Java内存模型&#xff08;JMM&#xff09;是Java虚拟机规范中定义的一种内存模型&#xff…

如何优化快速排序?

欢迎来到 Claffic 的博客 &#x1f49e;&#x1f49e;&#x1f49e; 前言&#xff1a; 还记得上次的快速排序吗&#xff1f;还记得 key 是怎么取的吗&#xff1f;当时我直接把数组的起始元素作为了 key 值&#xff0c;其实这样做是有弊端的&#xff0c;试想&#xff1a;一个降…

SAP Business Technology Platform (BTP)的架构理解

查资料看到的&#xff0c;转一下&#xff0c;附上链接&#xff1a; SAP Business Technology Platform (BTP)的架构理解 长期以来&#xff0c;我在与客户和伙伴的沟通交流中发现大家依然对SAP业务技术平台 – SAP Business Technology Platform (以下简称BTP)纯有各种疑惑&…

webgl-图形非矩阵旋转

知识拓展 由&#xff08;x1,y1&#xff09;旋转β角度到&#xff08;x2,y2&#xff09; 根据圆极坐标方程 x1 r*cosα y1 r*sinα 可得 x2 r*cos(α β) r*cosα*cosβ - r*sinα*sinβ,因为x1 r*cosα&#xff0c;y1 r*sinα&#xff0c;所以x2 x1*cosβ -y1*sinβ…

如何进行移动设备资产管理

随着越来越多的移动设备进入和访问组织的企业资源&#xff0c;管理员必须监视和控制对企业数据的访问。与传统工作站不同&#xff0c;传统工作站位于企业的物理工作区内&#xff0c;移动设备从多个位置使用&#xff0c;从而使移动资产管理过程更加复杂。 什么是移动资产管理 …

java基础集合面试题

什么是集合 集合就是一个放数据的容器&#xff0c;准确的说是放数据对象引用的容器 集合类存放的都是对象的引用&#xff0c;而不是对象的本身 集合类型主要有3种&#xff1a;set(集&#xff09;、list(列表&#xff09;和map(映射)。 集合的特点 集合的特点主要有如下两点&…

LMKD分享

背景 Android是一个多任务系统&#xff0c;可以同时运行多个程序&#xff0c;一般来说&#xff0c;启动运行一个程序是有一定的时间开销的&#xff0c;因此为了加快运行速度&#xff0c;当你退出一个程序时&#xff0c;Android并不会立即杀掉它&#xff0c;这样下次再运行该程…

【MySQL优化】快速入门慢SQL优化

MySQL B树结构&#xff08;二叉排序树&#xff09; 索引 SQL优化&#xff0c;主要就是在优化索引 索引:相当于书的目录 索引:index是帮助MYSQL高效获取数据的数据结构。索引是数据结构&#xff08;树:B树(默认)、Hash树…) 索引的弊端: 1.索引本身很大&#xff0c;可以存…

Spring Cloud Config配置服务及那些你不知道的坑

目录 1、为什么选择Spring Cloud Config 1.1 集中式管理 1.2 动态修改配置 2、Spring Cloud Config 简介 3、服务端配置 3.1 添加依赖 3.2 开启服务注册 3.3 添加YML配置 3.4 创建远程分支及Profile配置文件 3.5 启动并测试服务 4、客户端配置 4.1 添加依赖 4.2 开…

2.3-6循环链表

原理的单链表和循环单链表的区别&#xff1a; 初始化循环单链表时&#xff0c;使头节点next指针指向头节点。 判断循环单链表是否为空。 对比&#xff1a; 单链表&#xff1a;if(L->next NULL) 双链表&#xff1a;if(L->nextL) 判断循环单链表的结点p是否为表尾结点…