Skip to content

Instantly share code, notes, and snippets.

@SpexGuy
Created May 16, 2020 19:52
Show Gist options
  • Save SpexGuy/cb60f6c04821935da716d4fcf6464dea to your computer and use it in GitHub Desktop.
Save SpexGuy/cb60f6c04821935da716d4fcf6464dea to your computer and use it in GitHub Desktop.
const std = @import("std");
const Channel = std.event.Channel;
const Timer = std.time.Timer;
const warn = std.debug.warn;
pub const io_mode = .evented;
// Send the sequence 2, 3, 4, ... to channel 'ch'.
fn generate(ch: *Channel(u32)) void {
var i: u32 = 2;
while (true) : (i += 1) {
ch.put(i);
}
}
// Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'.
fn filter(in: *Channel(u32), out: *Channel(u32), prime: u32) void {
while (true) {
const i = in.get();
if (i % prime != 0) {
out.put(i);
}
}
}
// The prime sieve: Daisy-chain Filter processes.
pub fn main() anyerror!void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = &arena.allocator;
var primesish = try allocator.alloc(u32, 100000);
var timer = try Timer.start();
var ch = try allocator.create(Channel(u32));
ch.init(&[0]u32{}); // Unbuffered channel.
_ = async generate(ch);
var i: usize = 0;
while (i < 100) : (i += 1) {
const prime = ch.get();
primesish[i] = prime;
const ch1 = try allocator.create(Channel(u32));
ch1.* = undefined;
ch1.init(&[0]u32{});
const frame = try allocator.create(@Frame(filter));
frame.* = undefined;
frame.* = async filter(ch, ch1, prime);
ch = ch1;
}
while (i < primesish.len) : (i += 1) {
primesish[i] = ch.get();
}
const time = timer.lap();
warn("Zig took {d:.3}s", .{@intToFloat(f64, time) / 1000000000.0});
}
@SpexGuy
Copy link
Author

SpexGuy commented Jul 15, 2022

This example is broken, due to channels interacting with the event loop to run async on multiple threads. A better version can be found at https://gist.github.com/SpexGuy/953e5780cd2d2c524cba6a79f13076e6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment