之前做Opengl程序,用的的C#的SharpGL这个库,里面有各种奇怪绑定的函数,比如原型为:

void glInterleavedArrays(uint format, int stride, void * pointer);

的函数被他绑定成:

private static extern void glInterleavedArrays(uint format, int stride, int[] pointer);

然后我就被逼着学习了各种float[] 转 int[] 的方法,比较他们的效率(其实我还是感觉c++比较快,一个指针类型转换,欧啦)

下面是我写的各种数组赋值转换的方法和结果对比。

1.Marshal.Copy,存在数组到IntPtr,IntPtr到数组的2次拷贝【当T2不是Copy支持的类型会出错,之所以引入dynamic dTo 是因为使用T2[] dTo 无法编译通过】,处理2000000*100字节1120.0018ms

public static T2[] Arr2Arr<T1, T2>(T1[] from)
where T1: struct
where T2 :struct
{ int byteNum = from.Length * from[].Sizeof();
T2 testByte = new T2(); dynamic dFrom = from;
dynamic dTo = new T2[byteNum / testByte.Sizeof()]; IntPtr ptr = Marshal.AllocHGlobal(byteNum);
Marshal.Copy(dFrom, , ptr, from.Length);
Marshal.Copy(ptr, dTo, , dTo.Length);
return dTo;
}

2.unsafe的方法,通过指针获得IntPtr,减少了一次复制,速度变快【当T2不是Copy支持的类型会出错,之所以引入pFrom是因为无法fixed泛型T1[]】,处理2000000*100字节695.9993ms

public unsafe static T2[] Arr2Arr<T1, T2>(T1[] from, void * pFrom)
where T1 : struct
where T2 : struct
{
int byteNum = from.Length * from[].Sizeof();
T2 testByte = new T2();
dynamic dTo = new T2[byteNum / testByte.Sizeof()]; IntPtr ptr = new IntPtr(pFrom);
Marshal.Copy(ptr, dTo, , dTo.Length);
return dTo;
}

3.通过GCHandle获得IntPtr,然后复制【当T2不是Copy支持的类型会出错】,处理2000000*100字节930.0481ms

public static T2[] Arr2Arr2<T1, T2>(T1[] from)
where T1 : struct
where T2 : struct
{
var gch = GCHandle.Alloc(from,GCHandleType.Pinned);
IntPtr ptr = gch.AddrOfPinnedObject(); int byteNum = from.Length * from[].Sizeof();
T2 testByte = new T2();
dynamic dTo = new T2[byteNum / testByte.Sizeof()];
Marshal.Copy(ptr, dTo, , dTo.Length);
gch.Free();
return dTo;
}

4.Array.Copy的方法,原生的数组复制方法【没有了Copy,可以处理任意值类型】,处理2000000*100字节620.042ms

public static T2[] Arr2Arr3<T1, T2>(T1[] from)
where T1 : struct
where T2 : struct
{
int byteNum = from.Length * from[].Sizeof();
T2 testByte = new T2();
T2[] dTo = new T2[byteNum / testByte.Sizeof()]; Array.Copy(from, dTo, dTo.Length);
return dTo;
}

5.通过Buffer.BlockCopy拷贝数组,速度最快,感觉类似于c++的memcpy【没有了Copy,可以处理任意值类型】,处理2000000*100字节300.0329ms

public static T2[] Arr2Arr4<T1, T2>(T1[] from)
where T1 : struct
where T2 : struct
{
int byteNum = from.Length * from[].Sizeof();
T2 testByte = new T2();
T2[] dTo = new T2[byteNum / testByte.Sizeof()]; Buffer.BlockCopy(from, , dTo, , byteNum); return dTo;
}

测试部分代码:

byte[] from = new byte[];
from[] = ;
from[] = ; var last = DateTime.Now;
for (int i = ; i < ; i++)
{
。。。
}
Console.WriteLine((DateTime.Now- last).TotalMilliseconds);
//sizeof扩展方法
internal static class ExFunc
{
public static int Sizeof(this ValueType t)
{
return Marshal.SizeOf(t);
}
}

综上所述,Buffer.BlockCopy 适用场合最广泛,效率最高。

例子下载地址:http://files.cnblogs.com/files/chihirosan/Convert.zip

C#各种数组直接的数据复制/转换的更多相关文章

  1. 字节数组与String类型的转换

    还是本着上篇文章的原则,只不过在Delphi中string有点特殊! 先了解一下Delphi中的string 1. string = AnsiString = 长字符串,理论上长度不受限制,但其实受限 ...

  2. JSONObject.fromObject(map)(JSON与JAVA数据的转换)

    JSON与JAVA数据的转换(JSON 即 JavaScript Object Natation,它是一种轻量级的数据交换格式,非常适合于服务器与 JavaScript 的交互.) 上一篇文章中有这么 ...

  3. 【转】java中byte数组与int类型的转换(两种方式)----不错

    原文网址:http://blog.csdn.net/piaojun_pj/article/details/5903009 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法, ...

  4. 转载:JSONObject.fromObject(map)(JSON与JAVA数据的转换)

    转载网址:http://blog.sina.com.cn/s/blog_821025b70100wh6v.html JSON与JAVA数据的转换(JSON 即 JavaScript Object Na ...

  5. 一条sql解决.一张表的数据复制到另外一张表

    如何把一个表的数组复制到一张表?也许很多人会把这个表查出来的数据再插入到另外一张表里面,这样很麻烦又要写代码逻辑去处理,其实一条sql语句就可以把一张表的数据复制到另外一张表,或者一张表的某一条数据复 ...

  6. 【delphi】Byte数组与String类型的转换

    string string = AnsiString = 长字符串,理论上长度不受限制,但其实受限于最大寻址范围2的32次方=4G字节: 变量Str名字是一个指针,指向位于堆内存的字符序列,字符序列起 ...

  7. json 与其他数据 格式转换及json学习新得

    jsonobject   var a={"a","A"}   通过json都对象能很轻松的操作json数据 jsonString     var a=" ...

  8. 日期类&&包装类&&System类&&Math类&&Arrays数组类&&大数据类

    day 07 日期类 Date 构造函数 Date():返还当前日期. Date(long date):返还指定日期 date:时间戳--->距离1970年1月1日 零时的毫秒数 常用方法 日期 ...

  9. 零基础学习java------day14-----泛型,foreach,可变参数,数组和集合间的转换,Set,Map,

    1.泛型(jdk1.5以后出现) https://www.cnblogs.com/lwbqqyumidi/p/3837629.html#!comments (1)为什么要用泛型? 限制集合,让它只能存 ...

随机推荐

  1. .NET应用服务器

    昨天参加Oracle的一个活动,知道了WebLogic的强大,于是对应用服务器产生了兴趣. WebLogic是一个Java EE应用服务器(与Java EE对应的另外一个技术平台就是.NET). 为什 ...

  2. 增强学习(五)----- 时间差分学习(Q learning, Sarsa learning)

    接下来我们回顾一下动态规划算法(DP)和蒙特卡罗方法(MC)的特点,对于动态规划算法有如下特性: 需要环境模型,即状态转移概率\(P_{sa}\) 状态值函数的估计是自举的(bootstrapping ...

  3. 一步一步学Python(1) 基本逻辑控制举例和编码风格规范

    (1) 基本逻辑控制举例和编码风格规范 1.while死循环 2.for循环 3.if,elif,else分支判断 4.编码风格(官方建议) 版本:Python3.4 1.while死循环 #func ...

  4. 15个前卫的 HTML5 & CSS3 网页设计作品

    今天,我们编译收集一组使用 HTML5 和 CSS3 制作的精美网站.在此集合中,你可以看到平面设计,网页设计,作品集和企业网站设计实例. 响应式设计和基于 HTML5 & CSS3 编码的网 ...

  5. apache解析多个域名

    之前搭建了一个网站在这台服务器上,今天心血来潮准备搭建个word press 博客,准备使用二级域名 blog.xdlxb.cn 来解析. 只需要设置httpd.conf 文件就可以了 如下 开启重定 ...

  6. 在Android中实现service动态更新UI界面

    之前曾介绍过Android的UI设计与后台线程交互,据Android API的介绍,service一般是在后台运行的,没有界面的.那么如何实现service动态更新UI界面呢?案例:通过service ...

  7. Electro桌面应用开发之HelloWorld

    简介 Electron (http://http://electron.atom.io‎)提供了一个使用Node.js进行桌面应用开发的环境. 本文介绍了一个基于Electron的HelloWorld ...

  8. laravel5如何创建service provider和facade

    laravel5如何创建service provider和facade laravel5创建一个facade,可以将某个service注册个门面,这样,使用的时候就不需要麻烦地use 了.文章用一个例 ...

  9. 《ASP.NET SignalR系列》第四课 SignalR自托管(不用IIS)

    从现在开始相关文章请到: http://lko2o.com/moon 接着上一篇:<ASP.NET SignalR系列>第三课 SignalR的支持平台 一.概述 SignalR常常依托于 ...

  10. JavaScript资源大全

    目录 前端MVC 框架和库 包管理器 加载器 打包工具 测试框架 框架 断言 覆盖率 运行器 QA 工具 基于 Node 的 CMS 框架 模板引擎 数据可视化 编辑器 UI 输入 日历 选择 文件上 ...