Skip to content

Instantly share code, notes, and snippets.

@fjod
Created June 26, 2021 10:42
Show Gist options
  • Save fjod/41d4f4ecd8d1355a2e63a9e69366b68a to your computer and use it in GitHub Desktop.
Save fjod/41d4f4ecd8d1355a2e63a9e69366b68a to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
namespace chapsasParallel
{
[SimpleJob(launchCount: 10, warmupCount: 3, targetCount: 20)]
[MemoryDiagnoser]
public class Test
{
private HttpClient _client = new HttpClient();
private int tasksCount = 15;
private async Task<string> SampleLoad()
{
var ret = await _client.GetStringAsync("http://ya.ru");
Console.Write($"{Thread.CurrentThread.ManagedThreadId} returned {ret.Length} of text");
return ret;
}
[Benchmark]
public async Task<List<string>> A2() => await WhenAll();
[Benchmark]
public async Task<List<string>> A3() => await AsyncParallelVersion(tasksCount);
public async Task<List<string>> ParallelVersion(int degree)
{
var list = new List<string>();
var tasks = Enumerable.Range(0,tasksCount).Select( _ =>
{
var func = new Func<Task<string>>(async () => await SampleLoad());
return func;
}).ToList();
var l1 = tasks[0];
var z = await l1();
//parallel wont work here with async; must use GetAwaiter().GetResult() which I wont do
Parallel.For(0, tasks.Count, new ParallelOptions {MaxDegreeOfParallelism = degree},
async i => list.Add(await tasks[i]()));
return list;
}
public async Task<List<string>> WhenAll()
{
var list = new List<string>();
var tasks = Enumerable.Range(0,tasksCount).Select(async _ =>
{
var q = await SampleLoad();
list.Add(q);
}).ToList();
await Task.WhenAll(tasks);
return list;
}
public async Task<List<string>> AsyncParallelVersion(int degree)
{
var list = new List<string>();
var tasks = Enumerable.Range(0,tasksCount).Select( _ =>
{
var func = new Func<Task<string>>(async () => await SampleLoad());
return func;
}).ToList();
await ParalelForEachAsync(tasks, degree, async f =>
{
list.Add(await f());
});
return list;
}
public static Task ParalelForEachAsync<T>(IEnumerable<T> source, int degree, Func<T, Task> body)
{
async Task AwaitPartition(IEnumerator<T> partition)
{
using (partition)
{
while (partition.MoveNext())
{
await body(partition.Current);
}
}
}
return Task.WhenAll(
Partitioner.Create(source).GetPartitions(degree).AsParallel().Select(AwaitPartition));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment