Un fil un peu ancien, c'est 2022 maintenant
J'avais un tas de short
qui traînent (désolé, pas de int
s ;-) ) et j'ai pensé que ce serait cool de les avoir sous forme de tableau d'octets à la place. Après avoir lu toutes les différentes façons d'aborder la question, j'étais très confus et j'ai commencé à faire des tests comparatifs avec mes logiciels préférés.
(Le code devrait être facile à appliquer à tout type de base).
Il utilise BenchmarkDotNet
pour effectuer les tests et les analyses statistiques.
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>();
}
}
J'ai laissé le dernier, parce que si tu ajoutes juste un File.WriteAllBytes
à la fin de toutes les méthodes et les faire produire des résultats, soudainement BLOCKCOPY
est un peu plus rapide que SPANSTYLE
sur ma machine. Si quelqu'un d'autre est confronté à ce problème ou a une idée de la façon dont cela peut se produire, veuillez me le dire.
EDIT : Désolé, j'ai oublié d'inclure les résultats réels (attention : sur ma machine) car il fonctionne pendant un certain temps avec les paramètres standard et tout le réchauffement.
| 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 |