net mvc control cache c# performance validation .net-4.0 memorycache

c# - mvc - Prueba de rendimiento Memory Cache.Net 4.0: resultado sorprendente



net core memory cache (3)

¡El problema es la clase StopWatch que no se puede usar en máquinas multi-core! (Supongo que tiene una CPU multinúcleo). Tiene algo que ver con la forma en que el BIOS maneja ese contador cuando un hilo se mueve de un núcleo a otro (¡incluso una sola aplicación con hilos salta los núcleos!).

Editar:
Consulte - http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx : específicamente la sección de comentarios. También hay una publicación de stackoverflow: cronómetro .Net multinúcleo y con detección de hilos. . Fin Editar

He buscado alto y bajo para obtener el mejor método para medir el rendimiento de la aplicación y el más confiable que he encontrado es DateTime.UtcNow. Obtenga la hora de inicio y finalización y luego tome la diferencia entre ellos. Tienes que repetir el código lo suficiente como para pasar la baja precisión, pero ningún otro método que he encontrado proporciona una precisión más confiable .

¿Esta prueba de rendimiento es incorrecta o la memoria caché del sistema está funcionando con un rendimiento excepcional?

Este es mi resultado:
[13] número de interacciones 100000: 63 milisegundos
[14] número de interacciones 100000: 139 milisegundos
[12] número de interacciones 100000: 47 milisegundos
[15] número de interacciones 100000: 44 milisegundos
Fin de la prueba.

Hardware: Familia x86 Modelo 23 Stepping GenuineIntel ~ 2992 Mhz 3.327 MB, 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(); } } }


En mi máquina, es de aproximadamente 40 ms o 400 ns por llamada a GetItem.

Seguí las llamadas en el depurador, se trata de unas 2000 instrucciones por GetItem en mi máquina I7. Eso es más de lo que esperaría.


Se ve bien. Aunque los tiempos debajo de un segundo no son muy confiables; es posible que se haya topado con una recolección de basura, su PC podría hacer otra cosa por un tiempo breve, compilar JIT por primera vez, etc.

Entonces aumenta el conteo. Lo cual también debería hacer que los resultados para cada hilo terminen más juntos.

Una prueba que hice la semana pasada llegó a ocho millones de iteraciones por segundo (no mucho, pero aún así) singlethreaded. Así que sí, las PC son rápidas en estos días ;-)