在c#中将int[]转换为byte[]
本文关键字:byte 转换 int 中将 | 更新日期: 2023-09-27 17:54:46
我知道如何做到这一点:通过创建必要大小的字节数组,并使用for循环从int数组中强制转换每个元素。
我想知道是否有更快的方法,因为如果int
大于sbyte
,上面的方法似乎会中断。
如果您想要按位复制,即从一个int中获得4个字节,则使用Buffer.BlockCopy
:
byte[] result = new byte[intArray.Length * sizeof(int)];
Buffer.BlockCopy(intArray, 0, result, 0, result.Length);
不要使用Array.Copy
,因为它会尝试转换而不仅仅是复制。有关更多信息,请参阅MSDN页面上的备注。
除了接受的答案(我现在正在使用),Linq爱好者可以选择的一行代码是:
byte[] bytes = ints.SelectMany(BitConverter.GetBytes).ToArray();
我想,虽然,它会更慢…
有点老了,现在是2022年了…
我有一堆short
s躺在周围(对不起,没有int
s;-)),并认为将它们作为字节数组代替会很酷。在阅读了所有不同的方法之后,我感到非常困惑,并开始对我最喜欢的方法进行基准测试。
(代码应该易于应用于任何基类型。)
使用BenchmarkDotNet
进行实际测试和统计分析。
using System;
using System.Linq;
using System.Runtime.InteropServices;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
namespace ArrayCastingBenchmark;
public class Benchy {
private const int number_of_shorts = 100000;
private readonly short[] shorts;
public Benchy() {
Random r = new(43);
shorts = new short[number_of_shorts];
for (int i = 0; i < number_of_shorts; i++)
shorts[i] = (short) r.Next(short.MaxValue);
}
[Benchmark]
public ReadOnlySpan<byte> SPANSTYLE() {
ReadOnlySpan<short> shortSpan = new ReadOnlySpan<short>(shorts);
return MemoryMarshal.Cast<short, byte>(shortSpan);
}
[Benchmark]
public byte[] BLOCKCOPY() {
byte[] bytes = new byte[shorts.Length * sizeof(short)];
Buffer.BlockCopy(shorts, 0, bytes, 0, bytes.Length);
return bytes;
}
[Benchmark]
public byte[] LINQY() {
return shorts.Select(i => (byte) i).ToArray();
}
[Benchmark]
public byte[] BITCONVERTER() {
byte[] bytes = shorts.SelectMany(BitConverter.GetBytes).ToArray();
return bytes;
}
//[Benchmark]
//public void BINARYWRITER() {
// var fhandle = File.OpenHandle("_shorts_binarywriter.bin", FileMode.Create, FileAccess.Write);
// var binaryWriter = new BinaryWriter(new FileStream(fhandle, FileAccess.Write));
// foreach (var shorty in shorts)
// binaryWriter.Write(shorty);
// binaryWriter.Flush();
// binaryWriter.Close();
// fhandle.Close();
//}
}
internal class Program {
static void Main(string[] args) {
var summary = BenchmarkRunner.Run<Benchy>();
}
}
我留下了最后一个,因为如果你只是在所有方法的末尾添加一个File.WriteAllBytes
,并使它们实际产生一些输出,突然之间,BLOCKCOPY
在我的机器上比SPANSTYLE
快了一点。如果有人有这样的经历,或者有一个想法,这是如何发生的,请告诉我。
编辑:对不起,我忘了把实际结果包括在内(注意:在我的机器上),因为它在标准设置和所有预热下运行了很长一段时间。
| Method | Mean | Error | StdDev |
|------------- |------------------:|----------------:|----------------:|
| SPANSTYLE | 0.4592 ns | 0.0333 ns | 0.0666 ns |
| BLOCKCOPY | 15,384.8031 ns | 304.6014 ns | 775.3079 ns |
| LINQY | 175,187.7816 ns | 1,119.2713 ns | 1,046.9671 ns |
| BITCONVERTER | 9,053,750.0355 ns | 330,414.7870 ns | 910,058.2814 ns |