Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

@@ -0,0 +1,67 @@
long cmd record_update = app.recordUpdate
long cmd continuous_record_update = app.continuousRecordUpdate
long cmd integer = app.integer
long cmd record_inspect = app.recordInspect
long cmd continuous_record_inspect = app.continuousRecordInspect
long cmd map_lookup = app.mapLookup
long cmd continuous_map_lookup = app.continuousMapLookup
long cmd map_text_lookup = app.mapTextLookup
long cmd continuous_map_text_lookup = app.continuousMapTextLookup
long cmd text_equal = app.textEqual
long cmd continuous_text_equal = app.continuousTextEqual
long cmd text_contains = app.textContains
long cmd continuous_text_contains = app.continuousTextContains
long cmd float = app.float
long cmd bytes_concat = app.bytesConcat
long cmd text_concat = app.textConcat
long cmd list = app.list
long cmd map = app.map
long cmd list_read = app.listRead
long cmd map_read = app.mapRead
long cmd list_record = app.listRecord
long cmd list_record_read = app.listRecordRead
long cmd continuous_integer = app.continuousInteger
long cmd continuous_float = app.continuousFloat
long cmd continuous_list = app.continuousList
long cmd continuous_map = app.continuousMap
long cmd continuous_list_read = app.continuousListRead
long cmd continuous_map_read = app.continuousMapRead
long cmd continuous_list_record = app.continuousListRecord
long cmd continuous_list_record_read = app.continuousListRecordRead
long cmd continuous_text_concat = app.continuousTextConcat
long cmd continuous_bytes_concat = app.continuousBytesConcat
long cmd call_read = app.callRead
long cmd continuous_call_read = app.continuousCallRead
+393
View File
@@ -0,0 +1,393 @@
type Lookup {
values: Map<Int, Int>
index: Int
total: Int
}
selected(value: Int) (answer: Int) { answer = value }
selected(value: null) (answer: Int) { answer = 0 }
lookup(value: Int, state: Lookup) (next: Lookup) {
found = selected(get(state.values, state.index))
next = Lookup { values = state.values
index = state.index + 1
total = state.total + found }
}
mapLookup(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
values = reduce(putValue, input, {})
initial = Lookup { values = values
index = 0
total = 0 }
begin = dever.time.monotonicNanos()
final = reduce(lookup, input, initial)
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = final.total }
}
continuousMapLookup(ticks: Text) (samples: List<Sample>) {
samples = each(mapLookup, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
type TextLookup {
values: Map<Text, Int>
total: Int
}
type TextPair {
left: Text
right: Text
}
textEntry(entry: MapEntry<Int, Int>, state: Map<Text, Int>) (next: Map<Text, Int>) {
next = put(state, "lookup-key-" + int.toText(entry.key), entry.value)
}
textKey(entry: MapEntry<Text, Int>) (key: Text) { key = entry.key }
textLookup(key: Text, state: TextLookup) (next: TextLookup) {
found = selected(get(state.values, key))
next = TextLookup { values = state.values
total = state.total + found }
}
mapTextLookup(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
values = reduce(textEntry, entries(reduce(putValue, input, {})), {})
keys = each(textKey, entries(values))
initial = TextLookup { values = values
total = 0 }
begin = dever.time.monotonicNanos()
final = reduce(textLookup, keys, initial)
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = final.total + length(keys) - length(input) }
}
continuousMapTextLookup(ticks: Text) (samples: List<Sample>) {
samples = each(mapTextLookup, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
textPair(value: Int) (pair: TextPair) {
left = "compare-value-" + int.toText(value)
pair = TextPair { left = left
right = text.lower(text.upper(left)) }
}
matchedValue(matched: true) (value: Int) { value = 120 }
matchedValue(matched: false) (value: Int) { value = 0 }
equalTextPair(row: TextPair, total: Int) (next: Int) {
next = total + matchedValue(row.left == row.right)
}
containsTextPair(row: TextPair, total: Int) (next: Int) {
next = total + matchedValue(text.contains(row.left, row.right))
}
textEqual(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
rows = each(textPair, input)
begin = dever.time.monotonicNanos()
total = reduce(equalTextPair, rows, 0)
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = total + length(rows) - length(input) }
}
continuousTextEqual(ticks: Text) (samples: List<Sample>) {
samples = each(textEqual, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
textContains(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
rows = each(textPair, input)
begin = dever.time.monotonicNanos()
total = reduce(containsTextPair, rows, 0)
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = total + length(rows) - length(input) }
}
continuousTextContains(ticks: Text) (samples: List<Sample>) {
samples = each(textContains, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
type Sample {
elapsed_ns: Int
checksum: Int
}
type FloatSample {
elapsed_ns: Int
checksum: Float
}
addFloat(value: Int, state: Float) (next: Float) {
next = state + float.fromInt(value)
}
float(ticks: Text) (sample: FloatSample) {
bytes = dever.bytes.fromText(ticks)
zero = float.fromInt(0)
begin = dever.time.monotonicNanos()
total = reduce(addFloat, bytes, zero)
end = dever.time.monotonicNanos()
sample = FloatSample { elapsed_ns = end - begin
checksum = total }
}
joinBytes(value: Bytes, state: Bytes) (next: Bytes) {
next = dever.bytes.concat(state, value)
}
bytesConcat(ticks: Text) (sample: Sample) {
chunks = each(dever.bytes.fromText, text.split(ticks, ""))
empty = dever.bytes.fromText("")
begin = dever.time.monotonicNanos()
output = reduce(joinBytes, chunks, empty)
end = dever.time.monotonicNanos()
total = reduce(add, output, 0)
sample = Sample { elapsed_ns = end - begin
checksum = total }
}
joinText(value: Text, state: Text) (next: Text) {
next = state + value
}
textConcat(ticks: Text) (sample: Sample) {
chunks = text.split(ticks, ",")
begin = dever.time.monotonicNanos()
output = reduce(joinText, chunks, "")
end = dever.time.monotonicNanos()
sample = Sample {
elapsed_ns = end - begin
checksum = reduce(add, dever.bytes.fromText(output), 0)
}
}
add(value: Int, state: Int) (next: Int) {
next = state + value
}
appendValue(value: Int, state: List<Int>) (next: List<Int>) {
next = append(state, value)
}
putValue(value: Int, state: Map<Int, Int>) (next: Map<Int, Int>) {
key = length(state)
next = put(state, key, value)
}
mapped(entry: MapEntry<Int, Int>) (value: Int) {
value = entry.value
}
integer(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
begin = dever.time.monotonicNanos()
value = reduce(add, input, 0)
end = dever.time.monotonicNanos()
sample = Sample {
elapsed_ns = end - begin
checksum = value
}
}
list(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
begin = dever.time.monotonicNanos()
value = reduce(appendValue, input, [])
end = dever.time.monotonicNanos()
sample = Sample {
elapsed_ns = end - begin
checksum = sum(value)
}
}
map(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
begin = dever.time.monotonicNanos()
value = reduce(putValue, input, {})
end = dever.time.monotonicNanos()
sample = Sample {
elapsed_ns = end - begin
checksum = sum(each(mapped, entries(value)))
}
}
listRead(ticks: Text) (sample: Sample) {
values = reduce(appendValue, dever.bytes.fromText(ticks), [])
begin = dever.time.monotonicNanos()
total = sum(values)
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = total }
}
mapRead(ticks: Text) (sample: Sample) {
values = reduce(putValue, dever.bytes.fromText(ticks), {})
begin = dever.time.monotonicNanos()
total = sum(mapped, entries(values))
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = total }
}
type Record {
first: Int
second: Int
third: Int
}
appendRecord(value: Int, state: List<Record>) (next: List<Record>) {
next = append(state, Record { first = value
second = 0
third = 0 })
}
recordValue(row: Record) (value: Int) {
value = row.first + row.second + row.third
}
listRecord(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
begin = dever.time.monotonicNanos()
values = reduce(appendRecord, input, [])
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = sum(recordValue, values) }
}
listRecordRead(ticks: Text) (sample: Sample) {
values = reduce(appendRecord, dever.bytes.fromText(ticks), [])
begin = dever.time.monotonicNanos()
total = sum(recordValue, values)
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = total }
}
continuousInteger(ticks: Text) (samples: List<Sample>) {
samples = each(integer, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
continuousFloat(ticks: Text) (samples: List<FloatSample>) {
samples = each(float, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
continuousList(ticks: Text) (samples: List<Sample>) {
samples = each(list, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
continuousMap(ticks: Text) (samples: List<Sample>) {
samples = each(map, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
continuousListRead(ticks: Text) (samples: List<Sample>) {
samples = each(listRead, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
continuousMapRead(ticks: Text) (samples: List<Sample>) {
samples = each(mapRead, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
continuousListRecord(ticks: Text) (samples: List<Sample>) {
samples = each(listRecord, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
continuousListRecordRead(ticks: Text) (samples: List<Sample>) {
samples = each(listRecordRead, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
continuousTextConcat(ticks: Text) (samples: List<Sample>) {
samples = each(textConcat, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
continuousBytesConcat(ticks: Text) (samples: List<Sample>) {
samples = each(bytesConcat, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
type OwnedRecord {
name: Text
tags: List<Text>
count: Int
}
ownedRecord(value: Int) (row: OwnedRecord) {
name = "row-value-" + int.toText(value)
row = OwnedRecord { name = name
tags = [name]
count = value - length(name) - 1 }
}
inspectOwned(row: OwnedRecord) (value: Int) {
value = row.count + length(row.name) + length(row.tags)
}
forwardOwned(row: OwnedRecord) (value: Int) {
value = inspectOwned(row)
}
callRead(ticks: Text) (sample: Sample) {
rows = each(ownedRecord, dever.bytes.fromText(ticks))
begin = dever.time.monotonicNanos()
total = sum(forwardOwned, rows)
end = dever.time.monotonicNanos()
preserved = length(rows)
sample = Sample { elapsed_ns = end - begin
checksum = total + preserved - length(rows) }
}
continuousCallRead(ticks: Text) (samples: List<Sample>) {
samples = each(callRead, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
type Accumulator {
values: List<Int>
count: Int
}
appendField(value: Int, state: Accumulator) (next: Accumulator) {
values = append(state.values, value)
next = Accumulator { values = values
count = state.count + 1 }
}
recordUpdate(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
begin = dever.time.monotonicNanos()
state = reduce(appendField, input, Accumulator { values = []
count = 0 })
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = sum(state.values) + state.count - length(state.values) }
}
continuousRecordUpdate(ticks: Text) (samples: List<Sample>) {
samples = each(recordUpdate, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
appendInspected(value: Int, state: Accumulator) (next: Accumulator) {
count = length(state.values) + 1
values = append(state.values, value)
next = Accumulator { values = values
count = count }
}
recordInspect(ticks: Text) (sample: Sample) {
input = dever.bytes.fromText(ticks)
begin = dever.time.monotonicNanos()
state = reduce(appendInspected, input, Accumulator { values = []
count = 0 })
end = dever.time.monotonicNanos()
sample = Sample { elapsed_ns = end - begin
checksum = sum(state.values) + state.count - length(state.values) }
}
continuousRecordInspect(ticks: Text) (samples: List<Sample>) {
samples = each(recordInspect, [ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks, ticks])
}
+214
View File
@@ -0,0 +1,214 @@
use std::hint::black_box;
use std::time::{Duration, Instant};
#[derive(Debug, PartialEq)]
struct Fault {
message: String,
locations: Vec<&'static str>,
causes: Vec<String>,
}
impl Fault {
fn overflow(location: &'static str) -> Self {
Self {
message: "Int overflow".into(),
locations: vec![location],
causes: Vec::new(),
}
}
fn at(mut self, location: &'static str) -> Self {
self.locations.push(location);
self
}
}
struct Record {
first: i64,
second: i64,
third: i64,
}
struct OwnedRecord {
name: String,
tags: Vec<String>,
count: i64,
}
fn inspect_owned(row: &OwnedRecord) -> Result<i64, Fault> {
let partial = row
.count
.checked_add(row.name.chars().count() as i64)
.ok_or_else(|| Fault::overflow("inspect_owned"))?;
partial
.checked_add(row.tags.len() as i64)
.ok_or_else(|| Fault::overflow("inspect_owned"))
}
fn forward_owned(row: &OwnedRecord) -> Result<i64, Fault> {
inspect_owned(row).map_err(|error| error.at("forward_owned"))
}
fn owned_sum(rows: &[OwnedRecord]) -> Result<i64, Fault> {
let mut total = 0_i64;
for row in rows {
let projected = forward_owned(row).map_err(|error| error.at("call_read"))?;
total = total
.checked_add(projected)
.ok_or_else(|| Fault::overflow("call_read"))?;
}
Ok(total)
}
fn add(total: i64, value: i64) -> Result<i64, Fault> {
total
.checked_add(value)
.ok_or_else(|| Fault::overflow("add"))
}
fn record_value(row: &Record) -> Result<i64, Fault> {
let partial = row
.first
.checked_add(row.second)
.ok_or_else(|| Fault::overflow("record_value"))?;
partial
.checked_add(row.third)
.ok_or_else(|| Fault::overflow("record_value"))
}
fn record_sum(values: &[Record]) -> Result<i64, Fault> {
let mut total = 0i64;
for row in values {
let projected = record_value(row).map_err(|error| error.at("record_sum"))?;
total = total
.checked_add(projected)
.ok_or_else(|| Fault::overflow("record_sum"))?;
}
Ok(total)
}
fn measure(operation: &str, ticks: &str) -> Result<(i64, Duration), Fault> {
let source = black_box(ticks.as_bytes());
match operation {
"call_read" => {
let rows = source
.iter()
.map(|value| {
let name = format!("row-value-{value}");
OwnedRecord {
count: i64::from(*value) - name.chars().count() as i64 - 1,
tags: vec![name.clone()],
name,
}
})
.collect::<Vec<_>>();
let borrowed = black_box(&rows);
let begin = Instant::now();
let total = owned_sum(borrowed)?;
black_box(total);
let elapsed = begin.elapsed();
black_box(&rows);
Ok((total, elapsed))
}
"integer" => {
let begin = Instant::now();
let mut total = 0;
for value in source {
total = add(total, i64::from(*value)).map_err(|error| error.at("integer"))?;
}
Ok((black_box(total), begin.elapsed()))
}
"list_record_read" => {
let mut values = Vec::new();
for value in source {
values.push(Record {
first: i64::from(*value),
second: 0,
third: 0,
});
}
let borrowed = black_box(&values);
let begin = Instant::now();
let total = record_sum(borrowed)?;
black_box(total);
drop(values);
Ok((total, begin.elapsed()))
}
_ => panic!("unknown checked kernel"),
}
}
fn verify_errors() {
let fault = owned_sum(&[OwnedRecord {
name: "overflow".into(),
tags: vec!["preserved".into()],
count: i64::MAX,
}])
.unwrap_err();
assert_eq!(fault.message, "Int overflow");
assert_eq!(
fault.locations,
["inspect_owned", "forward_owned", "call_read"]
);
assert!(fault.causes.is_empty());
assert_eq!(add(i64::MAX, 0).unwrap(), i64::MAX);
assert_eq!(add(i64::MIN, 0).unwrap(), i64::MIN);
for (left, right) in [(i64::MAX, 1), (i64::MIN, -1)] {
let fault = add(left, right).unwrap_err().at("integer");
assert_eq!(fault.message, "Int overflow");
assert_eq!(fault.locations, ["add", "integer"]);
assert!(fault.causes.is_empty());
}
let fault = record_sum(&[Record {
first: i64::MAX,
second: 1,
third: 0,
}])
.unwrap_err();
assert_eq!(fault.locations, ["record_value", "record_sum"]);
let fault = record_sum(&[
Record {
first: i64::MAX,
second: 0,
third: 0,
},
Record {
first: 1,
second: 0,
third: 0,
},
])
.unwrap_err();
assert_eq!(fault.locations, ["record_sum"]);
}
fn main() {
let arguments = std::env::args().collect::<Vec<_>>();
if arguments[1] == "--verify-errors" {
verify_errors();
println!("checked overflow and error frames verified");
return;
}
let input: serde_json::Value = serde_json::from_str(&arguments[2]).expect("input object");
let ticks = input["ticks"].as_str().expect("ticks string");
let (operation, count) = arguments[1]
.strip_prefix("continuous_")
.map_or((arguments[1].as_str(), 1), |operation| (operation, 10));
let mut samples = Vec::new();
for _ in 0..count {
match measure(operation, ticks) {
Ok((checksum, elapsed)) => samples
.push(serde_json::json!({"checksum": checksum, "elapsed_ns": elapsed.as_nanos()})),
Err(error) => {
eprintln!("{error:?}");
std::process::exit(1);
}
}
}
let output = if count == 1 {
samples.pop().unwrap()
} else {
serde_json::Value::Array(samples)
};
println!("{output}");
}
+278
View File
@@ -0,0 +1,278 @@
package main
import (
"encoding/json"
"fmt"
"math"
"os"
"runtime"
"strconv"
"strings"
"time"
"unicode/utf8"
)
type input struct {
Ticks string `json:"ticks"`
}
type sample struct {
Elapsed int64 `json:"elapsed_ns"`
Checksum int64 `json:"checksum"`
}
type record struct {
First int64
Second int64
Third int64
}
type ownedRecord struct {
Name string
Tags []string
Count int64
}
func inspectOwned(row ownedRecord) int64 {
return checkedAdd(checkedAdd(row.Count, int64(utf8.RuneCountInString(row.Name))), int64(len(row.Tags)))
}
func forwardOwned(row ownedRecord) int64 {
return inspectOwned(row)
}
func checkedAdd(total, value int64) int64 {
if value > 0 && total > math.MaxInt64-value {
panic("overflow")
}
return total + value
}
func measure(operation string, ticks string) sample {
source := []byte(ticks)
total := int64(0)
elapsed := int64(0)
switch operation {
case "record_update":
var values []int64
count := int64(0)
begin := time.Now()
for _, value := range source {
values = append(values, int64(value))
count = checkedAdd(count, 1)
}
elapsed = time.Since(begin).Nanoseconds()
for _, value := range values {
total = checkedAdd(total, value)
}
total = checkedAdd(total, count) - int64(len(values))
case "record_inspect":
var values []int64
count := int64(0)
begin := time.Now()
for _, value := range source {
count = checkedAdd(int64(len(values)), 1)
values = append(values, int64(value))
}
elapsed = time.Since(begin).Nanoseconds()
for _, value := range values {
total = checkedAdd(total, value)
}
total = checkedAdd(total, count) - int64(len(values))
case "map_lookup":
values := make(map[int64]int64, len(source))
for index, value := range source {
values[int64(index)] = int64(value)
}
index := int64(0)
begin := time.Now()
for range source {
total = checkedAdd(total, values[index])
index = checkedAdd(index, 1)
}
elapsed = time.Since(begin).Nanoseconds()
case "text_equal", "text_contains":
rows := make([][2]string, len(source))
for index, value := range source {
left := "compare-value-" + strconv.Itoa(int(value))
rows[index] = [2]string{left, strings.ToLower(strings.ToUpper(left))}
}
begin := time.Now()
if operation == "text_equal" {
for _, row := range rows {
matched := int64(0)
if row[0] == row[1] {
matched = 120
}
total = checkedAdd(total, matched)
}
} else {
for _, row := range rows {
matched := int64(0)
if strings.Contains(row[0], row[1]) {
matched = 120
}
total = checkedAdd(total, matched)
}
}
elapsed = time.Since(begin).Nanoseconds()
runtime.KeepAlive(rows)
total = checkedAdd(total, int64(len(rows))) - int64(len(source))
case "map_text_lookup":
keys := make([]string, len(source))
values := make(map[string]int64, len(source))
for index, value := range source {
key := "lookup-key-" + strconv.Itoa(index)
keys[index] = key
values[key] = int64(value)
}
begin := time.Now()
for _, key := range keys {
total = checkedAdd(total, values[key])
}
elapsed = time.Since(begin).Nanoseconds()
runtime.KeepAlive(values)
runtime.KeepAlive(keys)
total = checkedAdd(total, int64(len(keys))) - int64(len(source))
case "call_read":
rows := make([]ownedRecord, 0, len(source))
for _, value := range source {
name := "row-value-" + strconv.Itoa(int(value))
rows = append(rows, ownedRecord{name, []string{name}, int64(value) - int64(utf8.RuneCountInString(name)) - 1})
}
begin := time.Now()
for _, row := range rows {
total = checkedAdd(total, forwardOwned(row))
}
elapsed = time.Since(begin).Nanoseconds()
case "float":
floating := 0.0
begin := time.Now()
for _, value := range source {
floating += float64(value)
}
elapsed = time.Since(begin).Nanoseconds()
total = int64(floating)
case "bytes_concat":
chunks := make([][]byte, len(source))
for index := range source {
chunks[index] = source[index : index+1]
}
var output []byte
begin := time.Now()
for _, chunk := range chunks {
output = append(output, chunk...)
}
elapsed = time.Since(begin).Nanoseconds()
for _, value := range output {
total = checkedAdd(total, int64(value))
}
case "text_concat":
chunks := strings.Split(ticks, ",")
begin := time.Now()
var output strings.Builder
for _, chunk := range chunks {
output.WriteString(chunk)
}
joined := output.String()
elapsed = time.Since(begin).Nanoseconds()
for index := 0; index < len(joined); index++ {
total = checkedAdd(total, int64(joined[index]))
}
case "integer":
begin := time.Now()
for _, value := range source {
total = checkedAdd(total, int64(value))
}
elapsed = time.Since(begin).Nanoseconds()
case "list":
var values []int64
begin := time.Now()
for _, value := range source {
values = append(values, int64(value))
}
elapsed = time.Since(begin).Nanoseconds()
for _, value := range values {
total = checkedAdd(total, value)
}
case "map":
values := make(map[int64]int64)
var order []int64
begin := time.Now()
for _, value := range source {
key := int64(len(values))
values[key] = int64(value)
order = append(order, key)
}
elapsed = time.Since(begin).Nanoseconds()
for _, key := range order {
total = checkedAdd(total, values[key])
}
case "list_read":
var values []int64
for _, value := range source {
values = append(values, int64(value))
}
begin := time.Now()
for _, value := range values {
total = checkedAdd(total, value)
}
elapsed = time.Since(begin).Nanoseconds()
case "map_read":
values := make(map[int64]int64)
var order []int64
for _, value := range source {
key := int64(len(values))
values[key] = int64(value)
order = append(order, key)
}
begin := time.Now()
for _, key := range order {
total = checkedAdd(total, values[key])
}
elapsed = time.Since(begin).Nanoseconds()
case "list_record":
var values []record
begin := time.Now()
for _, value := range source {
values = append(values, record{int64(value), 0, 0})
}
elapsed = time.Since(begin).Nanoseconds()
for _, value := range values {
total = checkedAdd(total, checkedAdd(checkedAdd(value.First, value.Second), value.Third))
}
case "list_record_read":
var values []record
for _, value := range source {
values = append(values, record{int64(value), 0, 0})
}
begin := time.Now()
for _, value := range values {
total = checkedAdd(total, checkedAdd(checkedAdd(value.First, value.Second), value.Third))
}
elapsed = time.Since(begin).Nanoseconds()
default:
panic("unknown kernel")
}
return sample{elapsed, total}
}
func main() {
var arguments input
if err := json.Unmarshal([]byte(os.Args[2]), &arguments); err != nil {
panic(err)
}
var result any
if operation, continuous := strings.CutPrefix(os.Args[1], "continuous_"); continuous {
samples := make([]sample, 0, 10)
for range 10 {
samples = append(samples, measure(operation, arguments.Ticks))
}
result = samples
} else {
result = measure(os.Args[1], arguments.Ticks)
}
output, err := json.Marshal(result)
if err != nil {
panic(err)
}
fmt.Println(string(output))
}
+306
View File
@@ -0,0 +1,306 @@
use indexmap::IndexMap;
use std::hint::black_box;
use std::time::Instant;
struct Record {
first: i64,
second: i64,
third: i64,
}
struct OwnedRecord {
name: String,
tags: Vec<String>,
count: i64,
}
fn inspect_owned(row: &OwnedRecord) -> i64 {
add(
add(row.count, row.name.chars().count() as i64),
row.tags.len() as i64,
)
}
fn forward_owned(row: &OwnedRecord) -> i64 {
inspect_owned(row)
}
fn add(total: i64, value: i64) -> i64 {
total.checked_add(value).expect("integer overflow")
}
fn record_value(row: &Record) -> i64 {
add(add(row.first, row.second), row.third)
}
fn measure(operation: &str, ticks: &str) -> serde_json::Value {
let source = black_box(ticks.as_bytes());
let (checksum, elapsed) = match operation {
"record_update" => {
let begin = Instant::now();
let mut values = Vec::new();
let mut count = 0;
for value in source {
values.push(i64::from(*value));
count = add(count, 1);
}
black_box((&values, count));
let elapsed = begin.elapsed();
let total = values.iter().fold(0, |total, value| add(total, *value));
let checksum = add(total, count)
.checked_sub(values.len() as i64)
.expect("integer overflow");
(checksum, elapsed)
}
"record_inspect" => {
let begin = Instant::now();
let mut values = Vec::new();
let mut count = 0;
for value in source {
count = add(values.len() as i64, 1);
values.push(i64::from(*value));
}
black_box((&values, count));
let elapsed = begin.elapsed();
let total = values.iter().fold(0, |total, value| add(total, *value));
let checksum = add(total, count)
.checked_sub(values.len() as i64)
.expect("integer overflow");
(checksum, elapsed)
}
"map_lookup" => {
let values = source
.iter()
.enumerate()
.map(|(index, value)| (index as i64, i64::from(*value)))
.collect::<IndexMap<_, _>>();
let borrowed = black_box(&values);
let mut index = 0;
let mut total = 0;
let begin = Instant::now();
for _ in source {
total = add(total, borrowed.get(&index).copied().unwrap_or(0));
index = add(index, 1);
}
black_box(total);
let elapsed = begin.elapsed();
black_box(&values);
(total, elapsed)
}
"text_equal" | "text_contains" => {
let rows = source
.iter()
.map(|value| {
let left = format!("compare-value-{value}");
let right = left.to_uppercase().to_lowercase();
(left, right)
})
.collect::<Vec<_>>();
let borrowed = black_box(&rows);
let mut total = 0;
let begin = Instant::now();
if operation == "text_equal" {
for (left, right) in borrowed {
total = add(total, if left == right { 120 } else { 0 });
}
} else {
for (left, right) in borrowed {
total = add(
total,
if left.contains(right.as_str()) {
120
} else {
0
},
);
}
}
black_box(total);
let elapsed = begin.elapsed();
black_box(&rows);
let checksum = add(total, rows.len() as i64)
.checked_sub(source.len() as i64)
.expect("integer overflow");
(checksum, elapsed)
}
"map_text_lookup" => {
// 与 Dever 使用相同的拥有键和插入顺序;HashMap<&str, _> 是不同的数据结构。
let values = source
.iter()
.enumerate()
.map(|(index, value)| (format!("lookup-key-{index}"), i64::from(*value)))
.collect::<IndexMap<_, _>>();
let keys = values.keys().cloned().collect::<Vec<_>>();
let borrowed = black_box(&values);
let mut total = 0;
let begin = Instant::now();
for key in &keys {
total = add(total, borrowed.get(key.as_str()).copied().unwrap_or(0));
}
black_box(total);
let elapsed = begin.elapsed();
black_box((&keys, &values));
let checksum = add(total, keys.len() as i64)
.checked_sub(source.len() as i64)
.expect("integer overflow");
(checksum, elapsed)
}
"call_read" => {
let rows = source
.iter()
.map(|value| {
let name = format!("row-value-{value}");
OwnedRecord {
count: i64::from(*value) - name.chars().count() as i64 - 1,
tags: vec![name.clone()],
name,
}
})
.collect::<Vec<_>>();
let borrowed = black_box(&rows);
let begin = Instant::now();
let total = borrowed
.iter()
.fold(0, |total, row| add(total, forward_owned(row)));
black_box(total);
let elapsed = begin.elapsed();
black_box(&rows);
(total, elapsed)
}
"float" => {
let begin = Instant::now();
let total = source
.iter()
.fold(0.0, |total, value| total + f64::from(*value));
black_box(total);
let elapsed = begin.elapsed();
(total as i64, elapsed)
}
"bytes_concat" => {
let chunks = source.chunks(1).map(<[u8]>::to_vec).collect::<Vec<_>>();
let begin = Instant::now();
let mut output = Vec::new();
for chunk in &chunks {
output.extend_from_slice(chunk);
}
black_box(&output);
let elapsed = begin.elapsed();
drop(chunks);
let total = output
.iter()
.fold(0, |total, byte| add(total, i64::from(*byte)));
(total, elapsed)
}
"text_concat" => {
let chunks = std::str::from_utf8(source)
.unwrap()
.split(',')
.map(str::to_owned)
.collect::<Vec<_>>();
let begin = Instant::now();
let mut output = String::new();
for chunk in &chunks {
output.push_str(chunk);
}
black_box(&output);
let elapsed = begin.elapsed();
drop(chunks);
let total = output
.bytes()
.fold(0, |total, byte| add(total, i64::from(byte)));
(total, elapsed)
}
"integer" => {
let begin = Instant::now();
let total = source
.iter()
.fold(0, |total, value| add(total, i64::from(*value)));
(black_box(total), begin.elapsed())
}
"list" | "list_read" => {
let mut values = Vec::new();
let begin = Instant::now();
values.extend(source.iter().map(|value| i64::from(*value)));
let construction = begin.elapsed();
let borrowed = black_box(&values);
let begin = Instant::now();
let total = borrowed.iter().fold(0, |total, value| add(total, *value));
black_box(total);
let traversal = begin.elapsed();
drop(values);
(
total,
if operation == "list" {
construction
} else {
traversal
},
)
}
"list_record" | "list_record_read" => {
let mut values = Vec::new();
let begin = Instant::now();
for value in source {
values.push(Record {
first: i64::from(*value),
second: 0,
third: 0,
});
}
let construction = begin.elapsed();
let borrowed = black_box(&values);
let begin = Instant::now();
let total = borrowed
.iter()
.fold(0, |total, row| add(total, record_value(row)));
black_box(total);
let traversal = begin.elapsed();
drop(values);
(
total,
if operation == "list_record" {
construction
} else {
traversal
},
)
}
"map" | "map_read" => {
let mut values = IndexMap::new();
let begin = Instant::now();
for value in source {
let key = i64::try_from(values.len()).expect("map size");
values.insert(key, i64::from(*value));
}
let construction = begin.elapsed();
let borrowed = black_box(&values);
let begin = Instant::now();
let total = borrowed.values().fold(0, |total, value| add(total, *value));
black_box(total);
drop(values);
let traversal = begin.elapsed();
(
total,
if operation == "map" {
construction
} else {
traversal
},
)
}
_ => panic!("unknown kernel"),
};
serde_json::json!({"checksum": checksum, "elapsed_ns": elapsed.as_nanos()})
}
fn main() {
let arguments = std::env::args().collect::<Vec<_>>();
let input: serde_json::Value = serde_json::from_str(&arguments[2]).expect("input object");
let ticks = input["ticks"].as_str().expect("ticks string");
let output = if let Some(operation) = arguments[1].strip_prefix("continuous_") {
serde_json::Value::Array((0..10).map(|_| measure(operation, ticks)).collect())
} else {
measure(&arguments[1], ticks)
};
println!("{output}");
}