三维数组赋值性能低下及跨类型数组拷贝优化咨询
三维数组类型转换的性能优化与Array.Copy使用方案
性能优化方案
你的嵌套循环速度慢主要源于两个问题:三维数组的索引计算开销,以及逐元素触发隐式转换的额外消耗。针对60×60×60的数组规模,以下是两种高效优化方式:
1. 直接内存拷贝(最优解)
你的SerializableQuaternion和Unity的Quaternion内存布局完全一致:都是4个按x/y/z/w顺序排列的float字段,内存占用均为16字节。这种情况下可以跳过类型转换逻辑,直接用Buffer.BlockCopy复制内存块,速度比循环快一个量级:
if (anro != null) { Rotate = new SerializableQuaternion[anro.GetLength(0), anro.GetLength(1), anro.GetLength(2)]; // 直接按内存字节拷贝,无需逐元素转换 Buffer.BlockCopy(anro, 0, Rotate, 0, anro.Length * sizeof(float) * 4); }
⚠️ 注意:如果后续修改SerializableQuaternion的字段顺序、类型,必须确保和Quaternion的内存布局完全匹配,否则会出现数据错乱。
2. 转一维数组优化循环
如果担心内存布局的兼容性问题,可以先把三维数组转成一维数组,减少索引计算的开销,再进行循环转换:
if (anro != null) { // 把三维Quaternion数组转成一维(内存连续,索引更快) Quaternion[] flatAnro = new Quaternion[anro.Length]; Buffer.BlockCopy(anro, 0, flatAnro, 0, anro.Length * sizeof(float) * 4); // 创建一维目标数组,循环转换 SerializableQuaternion[] flatRotate = new SerializableQuaternion[flatAnro.Length]; for (int i = 0; i < flatAnro.Length; i++) { flatRotate[i] = flatAnro[i]; } // 转回三维数组(如果需要保持原结构) Rotate = new SerializableQuaternion[anro.GetLength(0), anro.GetLength(1), anro.GetLength(2)]; Buffer.BlockCopy(flatRotate, 0, Rotate, 0, flatRotate.Length * sizeof(float) * 4); }
如何用Array.Copy处理不同类型数组
Array.Copy本身不支持不同值类型的自动转换(即使有隐式转换运算符),因为它是基于元素类型的直接拷贝,不会触发自定义转换逻辑。要实现跨类型拷贝,需要先将源数组转换为目标类型的数组,再进行拷贝:
实现方法:用Array.ConvertAll转换后再拷贝
if (anro != null) { // 转一维数组 Quaternion[] flatAnro = new Quaternion[anro.Length]; Buffer.BlockCopy(anro, 0, flatAnro, 0, anro.Length * sizeof(float) * 4); // 用Array.ConvertAll完成类型转换,内部会循环调用隐式转换 SerializableQuaternion[] flatRotate = Array.ConvertAll(flatAnro, q => (SerializableQuaternion)q); // 拷贝到三维数组 Rotate = new SerializableQuaternion[anro.GetLength(0), anro.GetLength(1), anro.GetLength(2)]; Array.Copy(flatRotate, 0, Rotate, 0, flatRotate.Length); }
注意:这种方式的性能不如直接内存拷贝,因为还是要逐元素触发转换,只是减少了三维数组的索引开销。
内容的提问来源于stack exchange,提问作者stingalimian galimian
相关产品推荐
相关产品推荐

