Array.Copy vs Buffer.BlockCopy
http://stackoverflow.com/questions/1389821/array-copy-vs-buffer-blockcopy
Since the parameters to Buffer.BlockCopy are byte-based rather than index-based, you're more likely to screw up your code than if you use Array.Copy,
so I would only use Buffer.BlockCopy in a performance-critical section of my code.
http://stackoverflow.com/questions/5099604/any-faster-way-of-copying-arrays-in-c
Use Buffer.BlockCopy. Its entire purpose is to perform fast (see Buffer):
This class provides better performance for manipulating primitive types than similar methods in the System.Array class.
Admittedly无可否认, I haven't done any benchmarks基准;标准检查程序, but that's the documentation. It also works on multidimensional多维 arrays; just make sure that you're always specifying how many bytes to copy, not how many elements, and also that you're working on a primitive基元 array.
Also, I have not tested this, but you might be able to squeeze挤 a bit more performance out of the system if you bind a delegate to System.Buffer.memcpyimpl
and call that directly. The signature is:
internal static unsafe void memcpyimpl(byte* src, byte* dest, int len)
It does require pointers, but I believe it's optimized for the highest speed possible, and so I don't think there's any way to get faster than that, even if you had assembly at hand.
Update:
Due to requests (and to satisfy my curiosity), I tested this:
using System; using System.Diagnostics; using System.Reflection; unsafe delegate void MemCpyImpl(byte* src, byte* dest, int len); static class Temp { //There really should be a generic CreateDelegate<T>() method... -___- static MemCpyImpl memcpyimpl = (MemCpyImpl)Delegate.CreateDelegate( typeof(MemCpyImpl), typeof(Buffer).GetMethod("memcpyimpl", BindingFlags.Static | BindingFlags.NonPublic)); const int COUNT = 32, SIZE = 32 << 20; //Use different buffers to help avoid CPU cache effects static byte[] aSource = new byte[SIZE], aTarget = new byte[SIZE], bSource = new byte[SIZE], bTarget = new byte[SIZE], cSource = new byte[SIZE], cTarget = new byte[SIZE]; static unsafe void TestUnsafe() { Stopwatch sw = Stopwatch.StartNew(); fixed (byte* pSrc = aSource) fixed (byte* pDest = aTarget) for (int i = 0; i < COUNT; i++) memcpyimpl(pSrc, pDest, SIZE); sw.Stop(); Console.WriteLine("Buffer.memcpyimpl: {0:N0} ticks", sw.ElapsedTicks); } static void TestBlockCopy() { Stopwatch sw = Stopwatch.StartNew(); sw.Start(); for (int i = 0; i < COUNT; i++) Buffer.BlockCopy(bSource, 0, bTarget, 0, SIZE); sw.Stop(); Console.WriteLine("Buffer.BlockCopy: {0:N0} ticks", sw.ElapsedTicks); } static void TestArrayCopy() { Stopwatch sw = Stopwatch.StartNew(); sw.Start(); for (int i = 0; i < COUNT; i++) Array.Copy(cSource, 0, cTarget, 0, SIZE); sw.Stop(); Console.WriteLine("Array.Copy: {0:N0} ticks", sw.ElapsedTicks); } static void Main(string[] args) { for (int i = 0; i < 10; i++) { TestArrayCopy(); TestBlockCopy(); TestUnsafe(); Console.WriteLine(); } } }
or, in other words: they're very competitive; as a general rule, memcpyimpl
is fastest, but it's not necessarily worth worrying about.
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2015-02-26 观察者模式和事件的不同之处
2015-02-26 Simple Factory vs. Factory Method vs. Abstract Factory【简单工厂,工厂方法以及抽象工厂的比较】