StackExchange.Redis
Profiling
Zoeken…
Opmerkingen
De profileringsfuncties van IProfiler
bestaan uit de IProfiler
interface en de ConnectionMultiplexer.RegisterProfiler(IProfiler)
, ConnectionMultiplexer.BeginProfiling(object)
, ConnectionMultiplexer.FinishProfiling(object)
.
Begint en eindigt profilering raadpleeg context object
zodat gerelateerde commando gegroepeerd kunnen worden.
Deze groepering werkt door uw IProfiler
interface te vragen naar een IProfiler
aan het begin van een opdracht, voordat er threading shenanigans zijn gebeurd, en die opdracht te associëren met andere opdrachten die hetzelfde contextobject hebben. Begin moet worden aangeroepen met hetzelfde contextobject, dus StackExchange.Redis weet profileeropdrachten te starten met dat contextobject en Finish wordt aangeroepen om het profileren te stoppen en de resultaten te retourneren.
Groepeer alle opdrachten uit een reeks threads samen
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);
Aan het einde zullen timings 16.000 IProfiledCommand-objecten bevatten - één voor elke opdracht die aan redis wordt gegeven.
Groepeer opdrachten op basis van het uitgeven van threads
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
heeft 16 ingangen van 1.000 IProfilingCommands, ingetoetst door de thread die ze heeft uitgegeven.