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

article/2025/8/23 14:18:02

        在 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://chatgpt.dhexx.cn/article/vNd90T6q.shtml

相关文章

Python报错ModuleNotFoundError: No module named ‘concurrent‘

在测试Python的多线程时&#xff0c;根据官方的说法&#xff0c;concurrent.futures在Python3中已经内置了&#xff0c;不需要下载安装&#xff0c;如果是Python2则需要运行pip install futures进行安装。。。 这样导入&#xff0c;两种写法均可 import concurrent.futures #…

go语言工具_Concurrent Map

Concurrent Map 背景 map是平时项目中经常用到的数据类型&#xff0c;但是如果多个协程去读写同一个map时&#xff0c;为了不发生数据错误&#xff0c;经常去将其和锁封装成一个新的map。像以下两种示例。 type LockMap struct { m map[interface{}]interface{} l…

C#线程安全队列ConcurrentQueue

ConcurrentQueue成员函数 入队(EnQueue) 、出队(TryDequeue) 、是否为空(IsEmpty)、获取队列内元素数量(Count)。 void Enqueue(T item) 入队函数&#xff0c;当队列已满时会自动增加队列容量。 bool TryDequeue(T* result) 尝试移除并返回并发队列开头处对象&#xff0c;…

项目优化>C++,concurrentqueue(高性能并发队列)

项目中的数据队列基于轮询和selep的实时性及CUP性能差&#xff0c;需要进行优化&#xff0c;尝试使用concurrentqueue进行优化。网上有一些资料介绍,可供参考。 使用后的个人理解:一个线程安全的queue&#xff0c;并且concurrentqueue的线程安全并不是一味的加锁&#xff0c;它…

ConcurrentMap

ConcurrentMap&#xff0c;它是一个接口&#xff0c;是一个能够支持并发访问的java.util.map集合&#xff1b; ConcurrentHashMap是一个线程安全&#xff0c;并且是一个高效的HashMap。 spring 缓存注解 通过查看源代码发现将数据存在ConcurrentMap中 1 Map并发集合 1.1 Co…

学习线程安全队列ConcurrentQueue

首先,基本使用&#xff1a;入队(EnQueue) 、出队(TryDequeue) 、是否为空(IsEmpty)、获取队列内元素数量(Count)。 一、ConcurrentQueue内部结构: 1.实现原理 众所周知&#xff0c;在普通的非线程安全队列有两种实现方式: 1.使用数组实现的循环队列。 2.使用链表实现的队列…

并发系列(六)-----concurrent的简单介绍

一 简介 concurrent包是jdk1.5引入的重要的包&#xff0c;主要代码由大牛Doug Lea完成。这个包下的一些类如果用好了可以很方便的保证数据在多线程下操作的正确性。就比如说线程共享的i&#xff0c;如果使用concurrent包下的Atomic系列类可以很方便的解决这个问题。这篇文章简单…

python并发之concurrent快速入门

导读&#xff1a;我很笨&#xff0c;但是我很快——计算机之所以计算能力如此出众&#xff0c;不在于其有多智能&#xff0c;而是因为它超快的执行速度&#xff0c;而多核心则可以进一步成倍的提高效率。在python中&#xff0c;concurrent库就是用于完成并发的模块之一。 01 初…

Java 并发工具包(concurrent)详解

目录 一、concurrent并发包 二、ReentrantLock&#xff08;可重入锁&#xff09; 1、锁状态中断与可重入 2、尝试非阻塞地获取锁 3、等待可中断 4、设置公平锁 三、CountDownLatch&#xff08;门栓&#xff09; 四、cyclicBarrier&#xff08;栅栏&#xff09; 五、…

JAVA中split函数的用法

JAVA中split函数的用法 只写经常使用的&#xff0c;并不完整。 1.基本用法&#xff0c;将字符串按照指定字符串进行分割&#xff0c;例如&#xff1a; public class Main {public static void main(String[] args) {String ss "abcabcdefg";String[] split ss.sp…

C语言实现split函数

实现类似JAVA编程语言中split函数&#xff1a; &#xff08;这里以空格为分隔符进行演示&#xff09; 函数的声明&#xff1a;void split(char *src,const char *separator,char **dest,int *num) {}变量&#xff1a; 1.*src&#xff1a;要进行分割的字符串地址&#xff0c; 2…

mysql实现自定义split函数

1、自定义split函数脚本 CREATE DEFINER root% FUNCTION tjdemo.fun_get_split_string_total(f_string varchar(1000),f_delimiter varchar(5)) RETURNS int(11) LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT BEGIN declare returnInt int(11…

Oracle实现split函数

创建TYPE CREATE OR REPLACE TYPE TYPE_SPLIT AS TABLE OF VARCHAR2 (4000);创建函数 CREATE OR REPLACE FUNCTION SPLIT(P_STRING VARCHAR2, P_SEP VARCHAR2 : ,)RETURN TYPE_SPLITPIPELINED ISIDX PLS_INTEGER;V_STRING VARCHAR2(4000) : P_STRING; BEGINLOOPIDX : INSTR(…

java split函数的用法_java中split函数用法以及注意事项

java中split函数用法以及注意事项 发布时间&#xff1a;2020-04-23 10:28:23 来源&#xff1a;亿速云 阅读&#xff1a;215 作者&#xff1a;小新 本篇文章和大家了解一下java中split函数用法以及注意事项。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希…

mysql 创建函数 split_在mysql中实现split函数的几种方法

在mysql中实现split函数的几种方法 关注:98 答案:2 mip版 解决时间 2021-02-07 11:27 提问者夜落花台 2021-02-07 02:11 在mysql中实现split函数的几种方法 最佳答案 二级知识专家蓝莓九栀 2021-02-07 03:28 mysql 5.* 的版本现在没有split 函数,以下是几个自定义的split函数…

Oracle split函数

一、创建split函数 1、创建TYPE CREATE OR REPLACE TYPE TYPE_SPLIT AS TABLE OF VARCHAR2 (4000); / 2、创建split函数 CREATE OR REPLACE FUNCTION SPLIT(P_STRING VARCHAR2, P_SEP VARCHAR2 : ,)RETURN TYPE_SPLITPIPELINED ISIDX PLS_INTEGER;V_STRING VARCHAR2(4000)…

mysql有split函数么_mysql中split函数

在mysql中并没有split函数,需要自己写: 1)获得按指定字符分割的字符串的个数: Sql代码 DELIMITER$$ DROP FUNCTION IFEXISTS`sims`.`func_get_split_string_total`$$ CREATE DEFINER=`root`@`localhost` FUNCTION `func_get_split_string_total`( f_strin 在mysql中并没有sp…

Python之split函数的详解

目录 一、split函数的官方定义 二、split函数的深刻理解 二、split函数的深刻理解 split函数主要应用场景是Python对字符串的处理中&#xff08;数据分析&#xff0c;数据处理&#xff09;&#xff0c;以及计算机二级考试的常考基础知识点。 一、split函数的官方定义 定义…

Python基础之split()函数

一、split()函数描述 split() 通过指定分隔符对字符串进行切片&#xff0c;如果参数 num 有指定值&#xff0c;则分隔 num1 个子字符串split() 方法语法&#xff1a; 二、split()用法 语法&#xff1a; str.split(str"", numstring.count(str)) 参数&#xff1a; str…

分割字符串split函数的正确用法(切片)

分割字符串split函数的正确用法&#xff08;切片&#xff09; split函数是将字符串分割为列表 函数原型&#xff1a; str.split(sep,maxsplit)参数说明&#xff1a; str:表示要进行分割的字符串sep:用于指定分隔符&#xff0c;可以包含多个字符&#xff0c;默认为None,即所有…