c#中list的性能优化

Richardicy 2015-01-12 05:12:44
小弟最近写了一段代码
用到了c# 的数据结构 list<byte> m_ArchiveData
在测试时发现,向m_ArchiveData中,使用m_ArchiveData.AddRange(value);来添加数据占用了很多时间
我们的需求是这样的
就是需要有个数据结构来存储流式数据,只会往数据的尾部添加数据,在解析的时候,只会从流的头开始,
一次读取数据
不知道是否C#里面有性能更好的方式
是否能直接使用byte[],C#的byte[]数组比较麻烦的地方就是似乎不能延展长度
...全文
1748 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
List<ArraySegment<byte>>可否?可以指定每个byte[]的偏移量
threenewbee 2015-01-13
  • 打赏
  • 举报
回复
(1)现在的机器,分配个100M的内存都不是个事 (2)缓冲区不同于你文件的大小。不是告诉你了么,用两个指针模拟队列的头尾。一个缓冲区可以放你很多条数据
Richardicy 2015-01-13
  • 打赏
  • 举报
回复
引用 22 楼 caozhy 的回复:
内存分配很占用资源 建议你一次分配一个足够大的空间作为缓冲区。变长又不是无限长。
不能一次性分配这么大的空间,因为上层传入的数据大小不固定 有可能是25k的图片数据,也有可能是8M以上的图片数据 有时也可能会是一个非常小的Command
threenewbee 2015-01-13
  • 打赏
  • 举报
回复
内存分配很占用资源 建议你一次分配一个足够大的空间作为缓冲区。变长又不是无限长。
腻害的小笼包 2015-01-13
  • 打赏
  • 举报
回复
用链表吧。。。
Richardicy 2015-01-13
  • 打赏
  • 举报
回复
我考虑可以用 list<byte[]>这样的方式来进行延展. byte[]的长度我可以指定为1024 但有个比较蛋疼的问题就是,我在往里面填数据的时候,如果填到每个byte[]的末尾 比如还剩1个字节,而我要填入的数据则是有4个字节 那就必然要把这4个字节分成1个字节+3个字节这样来进行写入了 解析的时候处理也不太好写
Richardicy 2015-01-13
  • 打赏
  • 举报
回复
引用 13 楼 Windowsvipcuvs 的回复:
用(byte[] or byte*) 首先在内存中划分一块足够大的 buffer 我不推荐你用 byte[] 我比较推荐你使用 byte* 用 stackalloc / heapAlloc 分配
谢谢,看来提高性能需要使用C#里面的unsafe编程,但现在有个问题就是我的数据结构非常复杂, 只有在处理完以后,byte*的总长度才可以知道,所以需要有类似C++ vector的自动变长机制来处理,不知道 byte[]有没有什么方法可以来延展长度的?
lincolnandlinda 2015-01-13
  • 打赏
  • 举报
回复
引用 16 楼 Richardicy 的回复:
[quote=引用 14 楼 caozhy 的回复:] 因为你的操作单位是byte 所以用指针+固定长度的数组自己构造一个队列比较好。
问题是这玩意是c#代码,我该咋用指针呢 如果C#能像C++那样直接操作内存的话就好了[/quote] 可以使用指针, 使用unsafe 代码
於黾 2015-01-13
  • 打赏
  • 举报
回复
在研究明白业务之前,不要纠结底层原理 byte数组根本不应该出现"慢"的问题 如果你说它"慢",那么必然是因为: 1.你在其他的地方处理速度太慢,跟用什么来存无关 2.你所谓的"快"要求太高,用台式机根本实现不了,你需要一个"银河"计算机
Richardicy 2015-01-13
  • 打赏
  • 举报
回复
引用 14 楼 caozhy 的回复:
因为你的操作单位是byte 所以用指针+固定长度的数组自己构造一个队列比较好。
问题是这玩意是c#代码,我该咋用指针呢 如果C#能像C++那样直接操作内存的话就好了
Richardicy 2015-01-13
  • 打赏
  • 举报
回复
似乎C#里面没有vector这种数据结构,像vector的话就是占用超出初始空间时,将占用空间翻倍
吹风的兔子 2015-01-13
  • 打赏
  • 举报
回复
不知道 楼主 纠结 这点性能作甚。 直接把 1.5G 的 电影文件,写入 内存 byte[] 或 MemoryStream 的飘过 —— 耗时只要 10秒钟。
Richardicy 2015-01-13
  • 打赏
  • 举报
回复
现在试下来MemoryStream的性能跑同样的业务流程是之前list<byte>的两倍以上 这个性能数据应该算是达标了 明天再试试unsafe的写法
於黾 2015-01-13
  • 打赏
  • 举报
回复
引用 26 楼 Richardicy 的回复:
[quote=引用 24 楼 caozhy 的回复:] (1)现在的机器,分配个100M的内存都不是个事 (2)缓冲区不同于你文件的大小。不是告诉你了么,用两个指针模拟队列的头尾。一个缓冲区可以放你很多条数据
我想了下,这种方法可能也会有问题,我们那个系统是个多线程系统,这么多线程公用一个buff的话势必涉及到锁的问题[/quote] 既然是多线程,不要多线程共用一个buff
Richardicy 2015-01-13
  • 打赏
  • 举报
回复
引用 24 楼 caozhy 的回复:
(1)现在的机器,分配个100M的内存都不是个事 (2)缓冲区不同于你文件的大小。不是告诉你了么,用两个指针模拟队列的头尾。一个缓冲区可以放你很多条数据
我想了下,这种方法可能也会有问题,我们那个系统是个多线程系统,这么多线程公用一个buff的话势必涉及到锁的问题
threenewbee 2015-01-12
  • 打赏
  • 举报
回复
因为你的操作单位是byte 所以用指针+固定长度的数组自己构造一个队列比较好。
相思梦 2015-01-12
  • 打赏
  • 举报
回复
用(byte[] or byte*) 首先在内存中划分一块足够大的 buffer 我不推荐你用 byte[] 我比较推荐你使用 byte* 用 stackalloc / heapAlloc 分配
winnowc 2015-01-12
  • 打赏
  • 举报
回复
性能好的方式是尽量不进行内存复制,但是你无论使用List<byte>还是MemoryStream都会进行复制,性能都会下降。(动态增长还会导致额外的复制) 理想的情况是你能实现无需中间buffer,直接使用原始的数据/缓冲区。不行的话,自行实现一个Stream,内部把获取到的一块块数据使用链表串起来,添加数据块的时候就是增长这个链表,读的时候实现逻辑来让使用者感觉和读一个完整的数据一样。具体的方式和数据块的大小、个数、还有是否知道数据量等等因素相关。
Richardicy 2015-01-12
  • 打赏
  • 举报
回复
引用 7 楼 sp1234 的回复:
如果说到“解析”,根本不是单纯作为“流”来处理的,因为需要在集合上进行反复计算。 如果实际的程序解析流程,根本不应该把对象看成是字节流,而你纠结于“流处理性能”,这就没有意义了。
所以你的建议是直接用MemoryStream来代替list<byte>?
Richardicy 2015-01-12
  • 打赏
  • 举报
回复
引用 4 楼 starfd 的回复:
你先进先出那就是Queue 先进后出就是Stack 然后你所谓的用了很长的时间,这个能具体化么?
是这样的,我这里表述不太好,我只是想问是否有别的什么数据结构,可以满足这样的需求,并且进一步提高性能
加载更多回复(9)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧