soa*_*dos 40 c# arrays type-conversion
我知道如何做到这一点:通过创建一个必要大小的字节数组并使用for循环来转换int数组中的每个元素.
我想知道是否有更快的方法,因为如果int大于一个方法,上面的方法似乎会破裂sbyte.
Dan*_*rth 85
如果你想要一个按位复制,即从一个int中获取4个字节,那么使用Buffer.BlockCopy:
byte[] result = new byte[intArray.Length * sizeof(int)];
Buffer.BlockCopy(intArray, 0, result, 0, result.Length);
Run Code Online (Sandbox Code Playgroud)
不要使用Array.Copy,因为它会尝试转换而不仅仅是复制.有关详细信息,请参阅MSDN页面上的备注.
一个有点旧的线程,现在是 2022 年\xe2\x80\xa6 \n我周围
有一堆s (抱歉,没有s ;-) ),并且认为将它们作为字节数组来代替会很酷。在阅读了所有不同的解决方法之后,我非常困惑,并开始对我最喜欢的方法进行基准测试。\n(代码应该很容易应用于任何基本类型。)\n它用于进行实际测试和统计分析。shortintBenchmarkDotNet
using System;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\n\nnamespace ArrayCastingBenchmark;\n\npublic class Benchy {\n private const int number_of_shorts = 100000;\n private readonly short[] shorts;\n\n public Benchy() {\n Random r = new(43);\n shorts = new short[number_of_shorts];\n for (int i = 0; i < number_of_shorts; i++)\n shorts[i] = (short) r.Next(short.MaxValue);\n }\n\n [Benchmark]\n public ReadOnlySpan<byte> SPANSTYLE() {\n ReadOnlySpan<short> shortSpan = new ReadOnlySpan<short>(shorts);\n return MemoryMarshal.Cast<short, byte>(shortSpan);\n }\n\n [Benchmark]\n public byte[] BLOCKCOPY() {\n byte[] bytes = new byte[shorts.Length * sizeof(short)];\n Buffer.BlockCopy(shorts, 0, bytes, 0, bytes.Length);\n return bytes;\n }\n\n [Benchmark]\n public byte[] LINQY() {\n return shorts.Select(i => (byte) i).ToArray();\n }\n\n [Benchmark]\n public byte[] BITCONVERTER() {\n byte[] bytes = shorts.SelectMany(BitConverter.GetBytes).ToArray();\n return bytes;\n }\n\n //[Benchmark]\n //public void BINARYWRITER() {\n // var fhandle = File.OpenHandle("_shorts_binarywriter.bin", FileMode.Create, FileAccess.Write);\n // var binaryWriter = new BinaryWriter(new FileStream(fhandle, FileAccess.Write));\n // foreach (var shorty in shorts)\n // binaryWriter.Write(shorty);\n // binaryWriter.Flush();\n // binaryWriter.Close();\n // fhandle.Close();\n //}\n}\n\ninternal class Program {\n static void Main(string[] args) {\n var summary = BenchmarkRunner.Run<Benchy>();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n我留下了最后一个,因为如果你只是File.WriteAllBytes在所有方法的末尾添加一个并让它们实际产生一些输出,突然变得比我的机器上BLOCKCOPY稍微快一些。SPANSTYLE如果其他人经历过这种情况或知道这种情况如何发生,请告诉我。
编辑:\n抱歉,忘记包含实际结果(请注意:在我的机器上),因为它在标准设置和所有预热下运行了相当长的一段时间。
\n | Method | Mean | Error | StdDev |\n |------------- |------------------:|----------------:|----------------:|\n | SPANSTYLE | 0.4592 ns | 0.0333 ns | 0.0666 ns |\n | BLOCKCOPY | 15,384.8031 ns | 304.6014 ns | 775.3079 ns |\n | LINQY | 175,187.7816 ns | 1,119.2713 ns | 1,046.9671 ns |\n | BITCONVERTER | 9,053,750.0355 ns | 330,414.7870 ns | 910,058.2814 ns |\nRun Code Online (Sandbox Code Playgroud)\n
除了已接受的答案(我现在正在使用),Linq爱好者的替代单行程将是:
byte[] bytes = ints.SelectMany(BitConverter.GetBytes).ToArray();
Run Code Online (Sandbox Code Playgroud)
不过,我想,它会慢一点......
| 归档时间: |
|
| 查看次数: |
55123 次 |
| 最近记录: |