aboutsummaryrefslogtreecommitdiffstats
path: root/docs/research/140-spec-suite.md
Commit message (Collapse)AuthorAgeFilesLines
* 140's 9, HTTP/1.1 requests a packet at a time (RFC 9112), written in aup ↵eunhhu4 days1-2/+87
| | | | with no new opcode (aup's examples/http.aup: each packet an event, its bytes added to what the last left, every request they complete read, h11's grammar): 200 streams (132,623 bytes, 578 requests: methods, targets, HTTP/1.1 and a last 1.0, mixed-case names, spaces around values, Content-Length and chunked bodies with extensions and trailers, some ending in part of a request) fed whole, at random boundaries and a byte at a time (the 50 under 400 bytes), the requests read h11's on every cut and the bytes left those after them, the three paths' outputs the same bytes; 200 damaged streams fed whole as http_requests.py (the Python reference) reads them, 35 refused by both and 165 the same; module_specs in make check: 80 streams and their reading (tests/specs/http, no h11 at check time) whole on the three paths and cut 88 ways; bars: written, three workarounds (the bytes left in a list of one: bytes are no state; names and codings compared as text: bytes have no ==; field lines returned in a record: a fn returns no bare list), 159 lines against Python's 79, 278 ns a byte against the same algorithm in C 3.27 (85x), pure Python 67 (its bytes methods are C: Pure 4.1x slower), h11 284; 140's decision point after 027: bytes alone as a state (inflate, HTTP) and bytes' == (DNS, HTTP) now each met by two written specs, so the two-spec rule lets them into the core (their design not begun); a view calling a block fn met by one (DNS); aup's three its compiler's; CHECKPOINT's direction row
* 140's DNS: the compiled path's 11% stated as measured (244 to 218 ns), which ↵eunhhu4 days1-1/+1
| | | | loops it compiled not looked at
* 140's 1, DNS messages (RFC 1035), written in aup with no new opcode (aup's ↵eunhhu4 days1-2/+70
| | | | examples/dns.aup: a message read by a handler into its header and records, names uncompressed in their wire form, those in NS, CNAME, PTR, MX, SOA and SRV data too, each pointer pointing before the last; written back by the view wire, the owners compressed): 400 messages dnspython made (148,582 bytes, 3,466 records: A, AAAA, NS, CNAME, PTR, MX, SOA, TXT, SRV, EDNS, shared suffixes, 63-byte labels, bytes above 0x7f, 245-byte names) read on the three paths as dnspython reads them (each section's records as a set) and written back to bytes dnspython reads as the same message, the paths' outputs the same bytes; 300 damaged messages as dns_message.py (the Python reference) reads them, 185 refused by both and 115 the same records and bytes; module_specs in make check: 200 of those messages (tests/specs/dns, no dnspython at check time) read on the three paths, written back and read again to the same state and bytes, 23 cut ones failing; dnspython shuffles a set's records unless want_shuffle is off, and merges a set's differing TTLs to the least; bars: written, two workarounds both the core's (bytes have no ==: TEXT_COMPARE takes text alone; a view calls no block fn: CALL is in handlers and functions alone), 115 lines against Python's 72, 244 ns a message byte read and written against the same algorithm in C 3.65 (67x), glibc's resolver reading alone 4.4, pure Python 131 (Pure 1.9x slower), 218 compiled; 63.6 instructions a byte, reading 42%, writing 58%; CHECKPOINT's direction row
* 140's inflate: the three workarounds' owners: a fn taking no bare list and a ↵eunhhu4 days1-0/+9
| | | | let's list only in its handler's own block are aup's (Pure's function signatures already take lists, type 4, moved by number and copied before a change; a block's list emptied by LIST_REMOVE or kept apart), a bytes value as a state alone is Pure's state kinds (a record alone aup could spread into states as it spreads record fields; bytes have no kind: text asks UTF-8), small block fns' inlining aup's; the two-spec rule gates the core alone
* 140's 3, inflate (RFC 1951), written in aup with no new opcode (aup's ↵eunhhu4 days1-2/+61
| | | | examples/inflate.aup, codes read a bit at a time from canonical counts as zlib's puff.c): 640 streams zlib made (6,488,480 bytes: random bytes, words, runs and repeats 32,768 back; levels 0, 1, 6, 9 and zlib's five strategies, so stored, fixed and dynamic blocks) inflated to the original's bytes on the three paths, the paths' outputs the same bytes; 240 damaged streams (cut, a bit flipped) read as inflate.py (the Python reference) reads them, 165 refused by both and 75 the same bytes; module_specs in make check: 144 streams on the three paths, 21 cut ones failing and leaving the last bytes; bars: written (no new opcode), three workarounds (lists passed in records: a fn takes no list; the output a list of one: a bytes value is no state; a block's tables built in a fn: a let's list lives in the handler's own block), 132 lines against Python's 81, 1,152 ns an output byte against the same algorithm in C 10.7 (108x) and zlib 3.5 (329x), pure Python 1,214; 191 instructions a byte (a block fn called for each bit was 246 and 1,553 ns: small block fns' inlining is 2c's leftover); the four timing tools' message calls fixed for 4b's API (no keys); CHECKPOINT's direction row
* 140 after 027: the ten probes compiled again (run.sh writing to a temporary ↵eunhhu4 days1-13/+47
| | | | directory: 10-13's -o /dev/null made a compiled probe say Permission denied): three compile as written, the other seven's diagnostics now mostly naming the form, so the same needs written in 027's forms (probes-027/): a byte an i64, bits on i64s, a record holding itself through a list, a recursive fn in a handler with its result type, a character by for and char, a variant in a list's item all compile; three gaps left, each a change of the core: a view calling a recursive fn or a fn with a block, a record or a variant as a state by itself, a character at a cursor; the suite table's column after 027 (2 and 4 written, 6 and 7 work, the first needs of 1, 3, 5 and 9 compiling, 8's layout as a view blocked by the first gap)
* Research 140, 027's stage 3 measured: a board of columns of cards of tags ↵eunhhu4 days1-0/+60
| | | | (aup's stored_nested) alike in memory and on a store restarting eight times, every step's fault, states and a view (2,400 snapshots, 54 restarts); killed at the tree's four stages and the log's two, all or nothing; replacement moving nested lists by name at depth; appending into a stored item's list costs about 170 ns an item it already holds (append_cost.c: 42 µs an add on average over the first 500, 738 µs over 8,000), building one by appends quadratic; instruction counts: the first commit's BFS +1.45% with batches and +1.68% without, from branches in the hot steps, gone with the load's internal ops (b29 against b27: BFS 0.000%/+0.034%, the others within 0.008%; the bank's queries -0.25% to +0.22%); what remains (a message's rows holding lists, a list field's .count in a fold, for over xs[i].f); 027's stage 3 as made (the representation chosen against the plan, its cost); 008's wording (kind 5 in images' headers alone); CHECKPOINT's direction row through stage 3
* Research 140, 027's stage 2c measured: JSON read into a tree by recursive ↵eunhhu4 days1-0/+65
| | | | descent (aup's examples/json_tree.aup: value(d, i) -> Json, number giving the value and where it ends, each call's own let's lists, string's escapes joined by char(u), a depth-first walk passing items as values) against Python's reading walked so: JSONTestSuite's 95 y_ taken alike, no n_ taken, 2b's 6 i_ taken (a lone surrogate refused by char as encoding); 100,000 and 50,000 deep refused as memory (the frames fill the event's room, 0.2 s), 30,000 deep taken (past Python's json); 300 random documents alike; in make check (module_specs' digest now depth first, three paths); 142 lines against the same design's 105 in Python (json_rec.py; the bar missed: 24 lines of declarations, 23 of braces), 46 times cJSON's time and 1.6 times plain Python's (600 ns a byte, 248 Pure instructions; 71% in the steps, about 10% in calls, 66,000 calls a document, most of them small block fns like skip); characters against Python's ord in aup's check; probes: p5-chars compiles, p4-rec (a view calling itself) refused; instruction counts: the workloads' modules the same, batches within 0.001% of 2b (BFS -0.21%), the executor alone -0.001% to +0.30%, the bank's queries -0.30% to +0.11% (four runs each; bar 1%); json_rec_time.c (cJSON, a depth-first digest compared first); CHECKPOINT's direction row through 2c
* Research 140: 2b's instruction counts: the workloads' modules the same, ↵eunhhu9 days1-0/+8
| | | | batches within 0.001% of 2a (BFS +0.36%, within its own runs' spread), the executor alone -1.3% to +0.4% (step's four cases more, mixed signs; -1.31% to +0.59% from before stage 1), the bank's queries -0.66% to +0.05% (four runs each; bar 1%); CHECKPOINT's direction row through 027's 2b
* Research 140, 027's stage 2b measured: JSON read into a tree (aup's ↵eunhhu9 days1-0/+46
| | | | examples/json_tree.aup: a variant, lists in records, match, appends into a field's list, number(t)) and walked for a digest, against Python's reading: JSONTestSuite's 95 y_ taken alike, no n_ taken, 6 i_ taken; 300 random nested documents alike; in make check (module_specs, the suite and 100 random documents, three paths); 167 lines against the same design's 133 in Python (the bar missed: the type declarations), 40 times cJSON's time and 1.3 times plain Python's (556 ns a byte, 525 instructions); json_tree.py, json_tree_time.c (cJSON linked, digests compared first)
* Research 140: 2a's instruction counts: the workloads' modules the same, the ↵eunhhu9 days1-0/+12
| | | | executor alone within 0.14% of stage 1, the bank's queries +0.28% to +0.80% where they hold still and +0.17% to +0.45% on average where they do not (four runs each; bar 1%): step's four cases more, not the held slots emptied each event (left to modules that hold some, the counts the same)
* Research 140, 027's stage 2a measured: whether bytes are JSON (aup's ↵eunhhu9 days1-0/+41
| | | | examples/json.aup, 80 lines against the same design's 90 in Python): JSONTestSuite's 95 y_ cases taken and 188 n_ refused, 21 of the 35 i_ taken, the three paths alike, in make check (module_specs, the 316 small cases in tests/specs/json under their MIT license, the two large ones made and hashed); 116 times C's time and 1.2 times plain Python's (299 ns a byte, 339 instructions); && and || made to decide alone (writing it, i < n && d[i] read past the end) with AND and OR kept where the right side cannot fail, every other module byte for byte the same; SHA-256 again with formats and joined bytes, 42 lines and 159 times C
* Research 140: stage 1's instruction counts: the workloads' modules byte for ↵eunhhu10 days1-1/+15
| | | | byte the same, the executor alone moved matmul +0.43% and BFS -0.34% (knapsack, roots, join within 0.03%; the bar of 0.1% missed, mixed signs: four cases more in step), the bank's queries -0.22% to 0.00% (bar 1%); the four cases out of line in a noinline function (b23) cost 6-15% of the executor's instructions (a call taking frame from step: the register cliff) and were taken back; CHECKPOINT's direction row through 027's stage 1
* Research 140, 027's stage 1 measured: SHA-256 written in aup (its ↵eunhhu10 days1-0/+60
| | | | examples/sha256.aup) right for FIPS 180-2's examples and 138 more messages on every path, in make check against hashlib; 52 lines against Python's 28 (the bar missed: no formatting, no bytes joined or sliced, no lists as values, moved into stage 2), 176 times C's time and 0.43 of plain Python's (1,591 ns a byte; a block's 19,129 instructions, 39% of them the inlined fn's literals not folded); 044's check, time.c against the same algorithm in C (digests compared first) and the Python reference
* Research 140: a suite of eleven specs from different fields (DNS, SHA-256, ↵eunhhu10 days1-0/+130
inflate, JSON, UTF-8 and line breaking, relational queries and graphs, text editing, box layout, HTTP/1.1 by packets, retries and timeouts, constant-time crypto) with five criteria (written in aup and Pure alone, no workaround, lines against a Python reference, time against C, the spec's own vectors passing in Pure's checks on three machines); ten probes (044) show today's aup stops at a byte by position, bit operations, nesting, recursion, variants and reading a character; the core's minimal candidates and the rule against piling up (only what two specs need); SHA-256 and JSON first