You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在循环中高效设置NativeArray<float4>的单个xyzw分量的值

遍历NativeArray修改单分量报错的高性能解决方案

当遍历NativeArray<float4>时,如果直接尝试设置每个float4的单个字段(比如本例的y分量)会触发编译报错,原因是索引取值得到的是结构体临时值,无法直接修改。

错误代码示例

NativeArray<float4> naFloat4s ;
void Start ( ) {
  naFloat4s = new NativeArray<float4> ( 96000, Allocator.Persistent ) ;
}
void MakeNoise ( ) {
  for ( int i = 0 ; i < naFloat4s.Length ; i++ ) {
    naFloat4s[i].y = Random.Range ( - 1f, 1f ) ;
  }
}

上述代码会触发「无法修改结构体临时值」的编译错误。

核心要求

解决方案需要满足以下条件:

  • 全程无GC垃圾生成
  • 可充分发挥NativeArray、Burst/Jobs的性能优势,可快速处理数万级别的数据赋值
  • 必须保留float4其余分量(x、z、w)的原有值不变
  • 示例中随机数仅为演示,可兼容其他自定义数值生成逻辑

最高性能实现方案(Unsafe指针操作)

通过直接操作float4内部的float指针实现单分量修改,完全规避临时值拷贝,性能损耗最低:

void LoopDemoWithPointerToFloatOfFloat4_NativeArray() {
  int    samples = 2000;
  int    size_T = UnsafeUtility.SizeOf<float4> ( ) ;
  int    size_F = UnsafeUtility.SizeOf<float> ( ) ;
  int    mStepr = size_F * 1 ; // 1对应float4结构体中y分量的偏移索引
  IntPtr dstPtr = ( IntPtr )NativeArrayUnsafeUtility
                   .GetUnsafeBufferPointerWithoutChecks ( naFloat4s ) ;
  
  for ( int i = 0 ; i < samples ; i++ ) {
    unsafe {
      float* yOffset =  (float*) (dstPtr + i * size_T + mStepr);
      *yOffset = (float)i ; // 此处可替换为自定义数值生成逻辑
    }
  }
}

实际使用简化示例

var p = (float4*)noizADSR.GetUnsafePtr (  );
float stepDekay = 1f / dekayLength ;
ptr = (float*)(p + attakFinish); ptr += nID;
j = overlapping;
for ( int i = attakFinish ; i < noizeLength ; i++, j++, ptr += 4 ) {
  *ptr = dekayCrv.Evaluate( j * stepDekay) ;
}

方案说明

  • 注意该实现需要在项目设置中开启unsafe编译选项
  • 该方案直接操作NativeArray的原生内存地址,无任何额外内存拷贝,性能最优
  • 完全兼容Burst编译和Job System调度,处理十万级以上数据时性能优势尤为明显
  • 无需修改其他分量的值,仅对目标分量做赋值操作,完全符合需求

内容的提问来源于stack exchange,提问作者Confused

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:48:02