StackExchange.Redis
StackExchange.Redis copied to clipboard
performance advise
Hello, Assuming funcAsync are mainly readAsync / writeAsync calls to Redis using the StackExchange.Redis client - which implementation of BatchExecuteAsync would be preferrable for better throughput / efficiency etc. ( especially when considering nature of the multiplexing going on behind the scenes ) ?
Thanks
public static async Task BatchedExecuteAsync<TItem>(this List<TItem> items, Func<TItem, Task> funcAsync, int amountOfParallelism)
{
var tasks = new List<Task>(amountOfParallelism);
int index = 0;
for (var i = 0; i < amountOfParallelism; i++)
{
tasks.Add(Task.Run(async () =>
{
while (true)
{
TItem item;
lock (tasks)
{
if (index >= items.Count)
{
break;
}
item = items[index];
index++;
}
await funcAsync(item);
}
}));
}
await Task.WhenAll(tasks);
}
public static async Task BatchedExecuteAsync<TItem>(this IEnumerable<TItem> items, Func<TItem,Task> funcAsync, int amountOfParallelism)
{
var tasks = new List<Task>(amountOfParallelism);
foreach (var item in items)
{
tasks.Add(funcAsync ( item));
if (tasks.Count == amountOfParallelism)
{
await Task.WhenAll(tasks);
tasks.Clear();
}
}
if (tasks.Count > 0)
{
await Task.WhenAll(tasks);
}
}
What are you trying to accomplish in your batching here? Why are you batching? (We need more context to answer this - looking immediately I couldn't recommend either implementation as there's extra async and allocation overhead happening when you can likely avoid it)
Hi, I'm trying to process many requests ( for example read requests for various keys ) - I assume sending them all and await them all together would incur too much load , so batching is used.
There's no significant difference between those two scenarios (with/without batch), except that when using the batch API you're delaying the first send by a few picoseconds (until you call execute). However: if your use case is reading multiple keys, then: a multi-key fetch already exists - maybe just use that? (if the key volume is huge you may want to split this into chunks so you don't block competing clients)