J'optimise actuellement une application, l'une des opérations qui se fait très souvent est la lecture et l'écriture binaire. Je besoin de 2 types de fonctions:Méthode la plus rapide de lecture et d'écriture binaire
Set(byte[] target, int index, int value);
int Get(byte[] source, int index);
Ces fonctions sont nécessaires pour faire court signé et non signé, int et long en grand et peu d'ordre endian.
Voici quelques exemples que j'ai fait, mais j'ai besoin d'une évaluation des avantages et des inconvénients:
première méthode consiste à utiliser le maréchal d'écrire la valeur dans la mémoire de l'octet [], le second est l'utilisation pointeurs simples pour ce faire et le troisième utilise BitConverter et BlockCopy pour ce faire
unsafe void Set(byte[] target, int index, int value)
{
fixed (byte* p = &target[0])
{
Marshal.WriteInt32(new IntPtr(p), index, value);
}
}
unsafe void Set(byte[] target, int index, int value)
{
int* p = &value;
for (int i = 0; i < 4; i++)
{
target[offset + i] = *((byte*)p + i);
}
}
void Set(byte[] target, int index, int value)
{
byte[] data = BitConverter.GetBytes(value);
Buffer.BlockCopy(data, 0, target, index, data.Length);
}
et voici la lecture/méthodes Get:
le premier utilise le maréchal pour lire la valeur de l'octet [], la seconde utilise plaine p ointers et le troisième est d'utiliser à nouveau BitConverter:
unsafe int Get(byte[] source, int index)
{
fixed (byte* p = &source[0])
{
return Marshal.ReadInt32(new IntPtr(p), index);
}
}
unsafe int Get(byte[] source, int index)
{
fixed (byte* p = &source[0])
{
return *(int*)(p + index);
}
}
unsafe int Get(byte[] source, int index)
{
return BitConverter.ToInt32(source, index);
}
vérification des frontières doit être fait, mais ne fait pas partie de ma question encore ...
Je serais heureux si quelqu'un peut dire quelle serait la le meilleur et le plus rapide dans ce cas ou donnez-moi d'autres solutions sur lesquelles travailler. Une solution générique serait préférable
Je viens de faire quelques tests de performance, voici les résultats:
Set Marshal: 45 ms, Set pointeur: 48 ms, Set BitConverter: 71 ms Get Marshal: 45 ms, Get Pointer: 26 ms, Get BitConverter: 30 ms
il semble que l'utilisation de pointeurs est la façon rapide, mais je pense que Marshal et BitConverter font une vérification interne ... quelqu'un peut-il vérifier cela?
Vous avez le code, pourquoi ne vous exécutez pas et test avec un 'Stopwatch'? –
: /: \ vous avez raison, je vais le faire rapidement et modifier ma question, mais ce n'est pas le seul point de mon message. Je cherche des alternatives et peut-être des façons génériques de le faire aussi – haze4real
Souris levé à cette question: la conversion en binaire ne devrait être nécessaire que pour les E/S. L'opération d'E/S elle-même est toujours plus lente de plusieurs ordres de grandeur que de masser les bits. La meilleure optimisation ne peut vous acheter plus de quelques pour cent d'amélioration. –