Skip to content

Improving the perfomance of the coro-prime-sieve algorithm in C# implementation #479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
333 changes: 319 additions & 14 deletions bench/algorithm/coro-prime-sieve/1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,344 @@ public static async Task Main(string[] args)

using var cts = new CancellationTokenSource();
var ch = Channel.CreateBounded<int>(s_channelOptions);
_ = GenerateAsync(ch.Writer, cts.Token);

using var output = Console.OpenStandardOutput();

GenerateAsync(ch.Writer, cts.Token);

for (var i = 0; i < n; i++)
{
var prime = await ch.Reader.ReadAsync().ConfigureAwait(false);
Console.WriteLine(prime);
if (!ch.Reader.TryRead(out var prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)

&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)

&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)

&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)

&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)

&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)

&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)

&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
&& !ch.Reader.TryRead(out prime)
)
{
var readed = ch.Reader.ReadAsync();
prime = readed.IsCompleted ? readed.Result : await readed.ConfigureAwait(false);
}

Span<byte> f = stackalloc byte[(int)Math.Ceiling(Math.Log10(prime)) + 1];
var c = prime;
var wI = 2;
while (c != 0)
{
const byte zero = (byte)'0';
f[^wI] = (byte)(zero + (c % 10));
c = c / 10;
wI += 1;
}

f[^1] = (byte)'\n';

output.Write(f);

var chNext = Channel.CreateBounded<int>(s_channelOptions);
_ = FilterAsync(ch.Reader, chNext.Writer, prime, cts.Token);

FilterAsync(ch.Reader, chNext.Writer, prime, cts.Token);

ch = chNext;
}
cts.Cancel();
}

static async Task GenerateAsync(ChannelWriter<int> writer, CancellationToken ct)
static void GenerateAsync(ChannelWriter<int> writer, CancellationToken ct)
{
for (var i = 2; !ct.IsCancellationRequested; i++)
ThreadPool.QueueUserWorkItem(async delegate
{
await writer.WriteAsync(i, ct).ConfigureAwait(false);
}
for (var i = 2; !ct.IsCancellationRequested; i++)
{
if (!writer.TryWrite(i))
{
try
{
var writed = writer.WriteAsync(i, ct);
if (!writed.IsCompleted) await writed;
}
catch { }
}
}
});
}

static async Task FilterAsync(
static void FilterAsync(
ChannelReader<int> reader,
ChannelWriter<int> writer,
int prime,
CancellationToken ct)
{
while (!ct.IsCancellationRequested)
ThreadPool.QueueUserWorkItem(async delegate
{
var n = await reader.ReadAsync(ct).ConfigureAwait(false);
if (n % prime != 0)
while (!ct.IsCancellationRequested)
{
await writer.WriteAsync(n, ct).ConfigureAwait(false);
if (!reader.TryRead(out var n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)

&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)

&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)

&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)

&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)

&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)

&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
&& !reader.TryRead(out n)
)
{
try
{
var readed = reader.ReadAsync(ct);
n = readed.IsCompleted ? readed.Result : await readed.ConfigureAwait(false);
}
catch { }
}

if (n % prime != 0)
{
if (!writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)

&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)

&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)

&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)

&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)

&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
&& !writer.TryWrite(n)
)
{
try
{
var writed = writer.WriteAsync(n, ct);
if (!writed.IsCompleted) await writed.ConfigureAwait(false);
}
catch { }
}
}
}
}
});
}
}