Ricerca…


Osservazioni

Le funzionalità di profilatura di StackExchange.Redis sono composte dall'interfaccia IProfiler e dai ConnectionMultiplexer.RegisterProfiler(IProfiler) , ConnectionMultiplexer.BeginProfiling(object) , ConnectionMultiplexer.FinishProfiling(object) .

Inizia e Finisci il profilo prendi un object contesto in modo che i relativi comandi possano essere raggruppati insieme.

Questo raggruppamento funziona interrogando l'interfaccia IProfiler per un oggetto di contesto all'inizio di un comando, prima che si verifichi qualsiasi shenanigans di threading e associando tale comando a qualsiasi altro comando che abbia lo stesso oggetto di contesto. Begin deve essere chiamato con lo stesso oggetto di contesto in modo che StackExchange.Redis sappia avviare i comandi di profilatura con tale oggetto di contesto e Fine viene chiamato per interrompere la profilazione e restituire i risultati.

Raggruppa tutti i comandi dal set di thread insieme

class ToyProfiler : IProfiler
{
    public ConcurrentDictionary<Thread, object> Contexts = new ConcurrentDictionary<Thread, object>();

    public object GetContext()
    {
        object ctx;
        if(!Contexts.TryGetValue(Thread.CurrentThread, out ctx)) ctx = null;

        return ctx;
    }
}


// ...

ConnectionMultiplexer conn = /* initialization */;
var profiler = new ToyProfiler();
var thisGroupContext = new object();

conn.RegisterProfiler(profiler);

var threads = new List<Thread>();

for (var i = 0; i < 16; i++)
{
    var db = conn.GetDatabase(i);

    var thread =
        new Thread(
            delegate()
            {
                var threadTasks = new List<Task>();

                for (var j = 0; j < 1000; j++)
                {
                    var task = db.StringSetAsync("" + j, "" + j);
                    threadTasks.Add(task);
                }

                Task.WaitAll(threadTasks.ToArray());
            }
        );

    profiler.Contexts[thread] = thisGroupContext;

    threads.Add(thread);
}

conn.BeginProfiling(thisGroupContext);

threads.ForEach(thread => thread.Start());
threads.ForEach(thread => thread.Join());

IEnumerable<IProfiledCommand> timings = conn.FinishProfiling(thisGroupContext);

Alla fine, i tempi conterranno 16.000 oggetti IProfiledCommand - uno per ogni comando emesso per redis.

Comandi di gruppo basati sul thread di emissione

ConnectionMultiplexer conn = /* initialization */;
var profiler = new ToyProfiler();

conn.RegisterProfiler(profiler);

var threads = new List<Thread>();

var perThreadTimings = new ConcurrentDictionary<Thread, List<IProfiledCommand>>();

for (var i = 0; i < 16; i++)
{
    var db = conn.GetDatabase(i);

    var thread =
        new Thread(
            delegate()
            {
                var threadTasks = new List<Task>();

                conn.BeginProfiling(Thread.CurrentThread);

                for (var j = 0; j < 1000; j++)
                {
                    var task = db.StringSetAsync("" + j, "" + j);
                    threadTasks.Add(task);
                }

                Task.WaitAll(threadTasks.ToArray());

                perThreadTimings[Thread.CurrentThread] = conn.FinishProfiling(Thread.CurrentThread).ToList();
            }
        );

    profiler.Contexts[thread] = thread;

    threads.Add(thread);
}

threads.ForEach(thread => thread.Start());
threads.ForEach(thread => thread.Join());

perThreadTimings termina con 16 voci di 1.000 IProfilingCommands, codificate dal Thread che le ha emesse.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow