-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
106 lines (90 loc) · 3.26 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using Dapper;
using Npgsql;
namespace Benchmark
{
public sealed class Program
{
public static void Main()
{
BenchmarkRunner.Run<Benchmarks>();
}
[MedianColumn]
public class Benchmarks
{
private const string ConnectionString =
"User ID=postgres;Password=postgres;Host=localhost;Port=5432;Database=postgres;Pooling=true;";
private const int Count = 500;
private static readonly HttpClient Client = new HttpClient();
private static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(10);
[Params(8080, 9080, 5000)]
public int Port { get; set; }
[Params(true, false)]
public bool Parallel { get; set; }
[Params("", "/date")]
public string Path { get; set; }
[GlobalSetup]
public void GlobalSetup()
{
using var connection = new NpgsqlConnection(ConnectionString);
connection.Execute("drop table if exists notes");
Thread.Sleep(1000);
connection.Execute(@"
create table if not exists notes (
id serial,
text varchar not null,
timestamp timestamptz default now() not null)");
Thread.Sleep(1000);
}
public static async Task Step(string url)
{
await Semaphore.WaitAsync(CancellationToken.None);
var post = await Client
.PostAsync(url, new StringContent(Guid.NewGuid().ToString()))
.ConfigureAwait(false);
var posted = await post.Content.ReadAsStringAsync().ConfigureAwait(false);
var id = posted.Split("\"id\":").Last().Split(",").First();
if (!string.IsNullOrWhiteSpace(id))
{
var note = await Client.GetStringAsync($"{url}/{id}").ConfigureAwait(false);
if (note != posted)
{
throw new InvalidOperationException($"get: {note}\npost: {posted}");
}
}
Semaphore.Release();
}
[Benchmark]
public void Benchmark()
{
var url = $"http://localhost:{Port}{Path}";
if (Parallel)
{
RunInParallel(_ => Step(url));
}
else
{
RunInSequence(url);
}
}
private static void RunInParallel(Func<int, Task> selector)
{
var tasks = Enumerable.Range(0, Count).AsParallel().Select(selector).ToArray();
Task.WaitAll(tasks);
}
private static void RunInSequence(string url)
{
for (var i = 0; i < Count; i++)
{
Step(url).GetAwaiter().GetResult();
}
}
}
}
}