La Mémoire Cache .Net 4.0 test de performance : résultat étonnant
Ce test de performance est mauvaise ou le système de cache est de travailler avec des performances exceptionnelles?
C'est mon résultat :
[13] le nombre d'interactions 100000 : 63 millisecondes
[14] le nombre d'interactions 100000 : 139 millisecondes
[12] le nombre d'interactions 100000 : 47 millisecondes
[15] le nombre d'interactions 100000 : 44 millisecondes
La fin du test.
Matériel :
x86 Family 6 Model 23 Stepping GenuineIntel ~2992 Mhz 3.327 MO, 5.1.2600 Service Pack 3
using System;
using System.Collections.Generic;
using System.Runtime.Caching;
using System.Diagnostics;
using System.Threading;
namespace CacheNet40
{
public class CacheTest
{
private ObjectCache cache;
public CacheTest()
{
cache = MemoryCache.Default;
}
public void AddItem(CacheItem item, double span)
{
CacheItemPolicy cp = new CacheItemPolicy();
cp.SlidingExpiration.Add(TimeSpan.FromMinutes(span));
cache.Add(item, cp);
}
public Object GetItem(string key)
{
return cache.Get(key);
}
}
class Program
{
private static CacheTest Cache = new CacheTest();
private static string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789!@$?_-";
private static int counter = 0;
private static readonly object locker = new object();
static string CreateRandomString(int passwordLength, int idx)
{
char[] chars = new char[passwordLength];
Random rd = new Random((int)DateTime.Now.Ticks + idx);
for (int i = 0; i < passwordLength; i++)
{
chars[i] = allowedChars[rd.Next(0, allowedChars.Length)];
}
return new string(chars);
}
private static void CacheAccessTes()
{
int span = 5;
string key;
string data;
int itens = 1000;
int interactions = 100000;
int cont = 0;
int index = 0;
List<string> keys = new List<string>();
lock (locker)
{
counter++;
}
cont = itens;
//populates it with data in the cache
do
{
key = CreateRandomString(127, Thread.CurrentThread.ManagedThreadId + cont);
keys.Add(key);
data = CreateRandomString(156000, Thread.CurrentThread.ManagedThreadId + cont + 1);
CacheItem ci = new CacheItem(key, data);
Cache.AddItem(ci, span);
cont--;
}
while (cont > 0);
cont = interactions;
index = 0;
//test readings
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
do
{
Object ci = Cache.GetItem(keys[index]);
ci = null;
index++;
if (index == itens)
{
index = 0;
}
cont--;
}
while (cont > 0);
stopWatch.Stop();
lock (locker)
{
counter--;
}
string outstring = String.Format("[{0}] number of interactions {1} : {2} milliseconds", Thread.CurrentThread.ManagedThreadId, interactions, stopWatch.ElapsedMilliseconds );
Console.WriteLine(outstring);
}
static void Main(string[] args)
{
for (int threads = 0; threads < 4; threads++)
{
Thread thread = new Thread(new ThreadStart(CacheAccessTes));
thread.Start();
}
Thread.Sleep(1000);
while (true)
{
lock (locker)
{
if (counter == 0) break;
}
Thread.Sleep(100);
}
Console.WriteLine("End of test.");
Console.ReadLine();
}
}
}
Semble OK pour moi. Ce qui vous fait douter les résultats?
Quel est le réel problème ici? Exactement ce qui est étonnant?
J'ai trouvé la performance extraordinaire, et cela m'a fait suspect.
Quel est le réel problème ici? Exactement ce qui est étonnant?
J'ai trouvé la performance extraordinaire, et cela m'a fait suspect.
OriginalL'auteur lsalamon | 2012-07-30
Vous devez vous connecter pour publier un commentaire.
Semble bon. Bien que les temps ci-dessous une seconde ne sont pas très fiables; vous pourriez avoir couru dans une poubelle recueillir, votre PC peut faire autre chose pendant une courte durée, d'abord à temps JIT compiler etc.
Afin d'augmenter le nombre de. Qui devrait également rendre les résultats de chaque extrémité du fil jusqu'à se rapprocher.
Quelques test que j'ai fait la semaine dernière, il fait de huit millions d'itérations par seconde (pas beaucoup, mais quand même) single thread. Donc oui, le PC est rapide ces jours 😉
OriginalL'auteur IvoTops
Le problème, c'est le Chronomètre de la classe qui ne peut pas être utilisé sur les systèmes multi-core machines! (Je suis en supposant que vous avez un PROCESSEUR multi-core) quelque Chose à voir avec la façon dont le BIOS gère le compteur lorsqu'un thread se déplace d'un coeur à un autre (même un seul thread de l'application des sauts de carottes!).
Edit:
Découvrez - http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs. 85).aspx - plus précisément, la section remarques.
Il y a un stackoverflow poste en tant que bien Multicœur et le thread courant .Net chronomètre?.
Fin Modifier
J'ai cherché haut et bas pour la meilleure méthode pour mesurer les performances de l'application et les plus fiables que j'ai est de type DateTime.UtcNow. Obtenez de départ et de fin, puis prendre la différence entre eux. Vous avez à votre boucle de code assez pour obtenir au-delà de la faible précision, mais pas d'autre méthode que j'ai trouver donne plus de fiable précision.
a lire votre article KB). L'article MSDN section remarques ne spécifie pas que tous les BIOS a ce bug, mais il n'a pas également spécifier que seuls quelques BIOS-s ont des bugs. Alors maintenant, cela dépend de comment vous interpet ce qui est écrit. Je maintiens que le texte dans la section des remarques implique que ces bugs sont largement présents et c'est pourquoi vous shoudln pas compter sur le chronomètre de donner des résultats précis sur les Processeurs multicœurs (sans réglage de l'affinité de thread). Il y a plusieurs messages sur le web de personnes ont des problèmes avec le chronomètre, qui devraient toutes l'appui de ma demande...
Je ne sais pas si le Chronomètre de la classe a été un problème dans ce cas (processeur spec ressemble à un Xeon mais ne sais pas si c'est du multi-core ou pas). Cependant, j'ai vraiment rencontré des problèmes avec le Chronomètre de classe dans mon propre code, donc je vous conseille de ne pas l'utiliser. Les problèmes ont inclus occasionnellement à venir avec un négatif intervalle de temps. Plus généralement, cependant, les valeurs successives sont manifestement inexactes, avec une valeur plus petite qu'une valeur antérieure.
... ne vous aime pas quand les gens il suffit de supprimer leurs bons-mauvais commentaires
OriginalL'auteur Marko
Sur ma machine, il est à environ 40 ms, ou 400 ns par GetItem appel.
J'ai tracé les appels en vertu de débogueur, c'est environ 2000 instructions par GetItem sur mon I7 machine. C'est plus que je ne l'attends.
OriginalL'auteur Feng Yuan
J'ai juste cherché sur le net pour plus d'informations sur
MemoryCache
performance et je suis tombé sur cette SORTE de question. Je me suis demandé pourquoi un bon indice de référence de la bibliothèque n'était pas utilisé, donc j'ai fini la cuisson de ma propre référence en étant très paresseux (comme tous les bons programmeurs devraient 🙂 et utilisé l'incroyable BenchmarkDotNet bibliothèque pour vérifier (ou non) cette classe se comporte.D'abord les résultats
Maintenant quelques explications...
J'étais surtout intéressé à voir comment rapide
MemoryCache
serait comparer haché listes (Dictionary
,Hashset
...) avec des milliers d'entrées, et aussi pour le pire des cas, la recherche linéaire sur la durée" de la liste. J'ai donc ajouté quelques tests supplémentaires et réalise que toutMemoryCache
n'est pas aussi rapide que le simple ou simultanées, listes, la vitesse se trouve encore à l'ordre de la nanoseconde à l'échelle. Pas même une seule milliseconde est pris pour extraire un élément dans un 30,000 longue liste des éléments mis en cache.Pour être juste
MemoryCache
fait BEAUCOUP plus que ceux de simples listes, comme il se doit de contrôle de la concurrence, élément d'expiration/de l'expulsion, etc. Je crois qu'il est assez rapide pour tous les types de charges de travail, mais si vous n'avez pas besoin de ces fonctionnalités supplémentaires, comme l'expulsion des politiques, il est préférable de coller avec le plus simple haché listes des implémentations.D'autre part, puisque c'est une commande d'une ampleur "plus lent" que d'un hachage de recherche, il peut y avoir de place pour l'amélioration. Je suppose que les concepteurs de la pensée, il est juste assez bon comme il est, et qui suis-je pour être en désaccord avec la DOTNET ingénieurs? 🙂
Voici le code source pour le programme de test:
OriginalL'auteur Loudenvier