<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pure/benchmarks/http/README.md, branch master</title>
<subtitle>Verified execution runtime unifying state, persistence, and replication.
</subtitle>
<id>http://git.yeowoo.org/pure/atom?h=master</id>
<link rel='self' href='http://git.yeowoo.org/pure/atom?h=master'/>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/'/>
<updated>2026-10-18T18:30:16Z</updated>
<entry>
<title>Module format v7, 027's 4b-2: keyed documents gone, a keyed list of records holding bytes doing their work: no collections table, DOC, DOC_SIZE or REPLACE (106 opcodes now 103, those from LEN on moved up), keyed messages or a base revision (pure_app_message takes an input and a payload), no PureData document callbacks (a data host opens states and saves them together), no burst by document key; the header 38 bytes; pure-edit-module gone; pure-serve without /objects, ETag, If-Match and If-None-Match, 412 or an app a thread for a module of documents alone (one without states or outputs runs so); a hole closed: an instruction in no handler's, view's or function's block was never verified yet the load's later passes read its arguments (a damaged module read out of bounds once the header moved what the mutation test damaged), now blanked to CONST 0; checks moved: server_documents (DOCS_SOURCE, keyed byte documents with the app's revision, against a Python model, one and three connection threads, a restart) in place of the parity with editor.pure, pipelining and bursts through kill -9 on its inputs and views, the lent budget on a text view (lending a document's read is server_lent_views' already), clocks and tokens on it; message tests without a document host; the HTTP benchmark's document suite runs the earlier document server and the baselines alone; the count harness builds against either message API (runs.sh build: -DPURE_KEYED_MESSAGES before 4b); counts: b33 against b32 with batches within 0.002% but BFS -0.33%, without batches BFS +0.63%, knapsack +0.52%, join +0.38%; the bank's queries (s32 on a v6 module, s33 on v7) field +0.68%, found +0.44%, large +0.42%, the rest within 0.13%; 008 as v7, 027's 4b-2 as made and 4c designed</title>
<updated>2026-10-18T18:30:16Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-18T18:30:16Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=b22b8c3f6c5378b47c36370225d7c41d4394bb7c'/>
<id>urn:sha1:b22b8c3f6c5378b47c36370225d7c41d4394bb7c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Add a sampling profiler for machines without perf</title>
<updated>2026-09-27T17:47:05Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T17:47:05Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=76f5edb2bcc227c2be743873753792dbc5af1f48'/>
<id>urn:sha1:76f5edb2bcc227c2be743873753792dbc5af1f48</id>
<content type='text'>
benchmarks/sample.c runs a command and samples where its threads spend
user time (the task clock every 50 us, one perf_event_open event a CPU,
since the kernel maps no ring for an inherited per-task event), then
names the samples from the ELF symbol tables of the files the command had
mapped: a stripped library from its debug file by build id. On arm64 it
also takes the link register, so time in a library's leaf (memcpy,
strcmp) is shown again by its caller. The command's user and system time
head the report.

</content>
</entry>
<entry>
<title>Lay Pure out as a core with the parts selected around it</title>
<updated>2026-09-27T12:14:38Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T12:14:38Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=37d3a1e152707d2da587440c4cea8601b9ef0fd2'/>
<id>urn:sha1:37d3a1e152707d2da587440c4cea8601b9ef0fd2</id>
<content type='text'>
The app model, the tree store and the HTTP host lived in
prototypes/connections among the earlier document runtime, the store was
known only by its format's name, and Vega compiled six Pure sources by path.
Now, as the README's principle has it:

  core/   runtime, flow and the app model (module*.c), with what the core
          asks of storage (state.h, store.h)
  store/  the tree store (PURETRE3, PUREREC1)
  serve/  pure-serve: HTTP host, outbound delivery, JSON in place
  cli/    pure-run, pure-edit-module

A top-level make builds libpure.a (app model and store, for hosts to link)
and the hosts; make check runs the store's and the app model's tests. The
earlier runtime still builds from prototypes/connections against core/ and
store/ (check, check-tree and check-core pass). Design 009 records the rule:
parts by role behind libraries; git repositories split by coupling, so the
store stays here while its contract moves with the core, and Vega stays apart.

</content>
</entry>
<entry>
<title>Read JSON bodies in place, groups included (082)</title>
<updated>2026-09-27T06:30:51Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T06:30:51Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=eb37aad3ae7f9df1d6c0b09108e3a2d69d0d4d82'/>
<id>urn:sha1:eb37aad3ae7f9df1d6c0b09108e3a2d69d0d4d82</id>
<content type='text'>
pure-serve no longer copies a JSON body's strings into the message's
payload. The ingress is the prefix, a table of each field's start and
size, and the body as it came; the connection thread scans the body
once, puts numbers into the prefix and records where each string is.
Only a string with escapes is unescaped, over itself (it never grows).
A group of fields comes as an object inside the body and, for a fixed
field, as its path in the query (?to.zip=7). A group where a field
belongs, a value where a group does, an array or true/false/null is
json_type; an unknown member, inside a group too, json_field.

The string scan and UTF-8 checks now pass over eight bytes at a time
while none needs a look (pure_utf8_step, so every text check gains).
On the Pi, posting {"name":"k","text":"x..."} to a stateless app went
from 652-655 to 3,737-3,953 requests/s with 256 KiB of text (server
CPU 1.52 to 0.25 ms a request, peak RSS 5.2 to 3.2-3.4 MiB) and from
29.1k to 76.3-76.7k/s with 4 KiB; the load generator gains a json
method and benchmarks/http/echo.aup is the app.

</content>
</entry>
<entry>
<title>Show views from the last save's snapshot on connection threads (080)</title>
<updated>2026-09-26T21:56:47Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T21:56:47Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=a51232af741cb952d7deb72f238c583919ababc0'/>
<id>urn:sha1:a51232af741cb952d7deb72f238c583919ababc0</id>
<content type='text'>
The owner publishes a snapshot of the saved states after every save,
before it hands back the answers; connection threads take the newest
one each round and show views from it with a reader app of their own.
A read made after a write's answer sees the write, nothing unsaved or
undone is ever shown, and reads no longer wait while the owner applies
events or syncs. Apps with states always get an owner thread, even
with one connection thread. A round's inputs go to the owner first;
its views are shown and then answered together (answering each one as
it was shown made one thread's 20-row page 8% slower).

On the Pi 5, with 8 connections posting durable scores and 56 reading
the total, reads went from 10-16k/s at p99 13-29 ms to 107-149k/s at
p99 0.6-0.7 ms, and posts stayed in range; axum and drogon, which sync
under their lock, read 1.1-1.3k/s at p99 111-156 ms. A snapshot of a
changed 1,024-item list costs 1.2 us (65,536 items: 87 us) against a
3-4 ms save.

</content>
</entry>
<entry>
<title>Measure reads made while durable writes go on</title>
<updated>2026-09-26T21:56:39Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T21:56:39Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=ea631f980a029141cd0b4835f35b27cd487ff3ea'/>
<id>urn:sha1:ea631f980a029141cd0b4835f35b27cd487ff3ea</id>
<content type='text'>
The app suite's last workload, mixed, runs two load generators at once:
8 connections post durable scores while 56 read the total. It shows
whether a server's reads wait while its writes sync. It is reported as
two rows, posts and reads; answers per CPU second count both.

</content>
</entry>
<entry>
<title>Record the app service against axum and drogon (077)</title>
<updated>2026-09-26T16:39:03Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T16:39:03Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=62f4c51920129216ea779118c341379b5e9f4d7c'/>
<id>urn:sha1:62f4c51920129216ea779118c341379b5e9f4d7c</id>
<content type='text'>
The scoreboard, 22 lines of aup served by its views and inputs, against
the same service written by hand in axum and drogon on the Pi: durable
posts about 76 times as many, reads level with drogon and ahead of axum
with the least CPU and memory. The note keeps what the profile showed on
the way (the kernel's share of a single thread, integers through printf,
an owner that saved too early) and what comes next. run.py gains
pure-serve-2 and waits for a server that prints its port before it
listens.

</content>
</entry>
<entry>
<title>Compare the HTTP host with drogon and by CPU time</title>
<updated>2026-09-26T06:42:00Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T06:42:00Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=4ebd1cd9108b135c1216bc6ae17832b77dcacaf3'/>
<id>urn:sha1:4ebd1cd9108b135c1216bc6ae17832b77dcacaf3</id>
<content type='text'>
A drogon 1.9 service with the axum baseline's contract joins the benchmark
(memory, fdatasync and crash-safe modes, three IO threads), built from
Debian's packages unpacked under .deps without installing them. drogon
listens once per event loop, so the service picks a free port itself:
with port 0 every loop got a port of its own and the load reached one.

The load generator has one core and saturates near 150k answers a second,
so the harness now also reports answers per second of server CPU time
(all threads). Over three rotated rounds: small GETs 151.6k/s on three
shards (drogon 145.3k, axum 120.9k) and 128k per CPU-second on one thread
(drogon 65k, axum 62k); 1 MiB GETs 2,794/s (axum 1,372, drogon 708);
crash-safe PUTs 5.1-5.8 times axum and 13-30 times drogon; peak RSS
5.0 MiB against 14.4 and 76.5 MiB. --workloads is now a regular expression.

</content>
</entry>
<entry>
<title>Compare durable writes on a device in the same state</title>
<updated>2026-09-26T05:47:25Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T05:47:25Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=0ea774f20703270a837c0f52adb0b44448a9a93a'/>
<id>urn:sha1:0ea774f20703270a837c0f52adb0b44448a9a93a</id>
<content type='text'>
An SD card slows down under sustained syncs, so the order of runs alone
changed write results several times over. The HTTP benchmark now repeats
rounds with the servers in a rotated order, gives every run a fresh store,
times the device (an in-place 4 KiB write + fdatasync) before each write
workload and reports medians over rounds with the probe range beside them.
--workloads picks workloads by label prefix.

</content>
</entry>
<entry>
<title>Serve modules over persistent connections</title>
<updated>2026-09-26T04:40:20Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T04:40:20Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=7771461a93f993425f97d4e05c91e64d17179e60'/>
<id>urn:sha1:7771461a93f993425f97d4e05c91e64d17179e60</id>
<content type='text'>
pure-serve replaces the module mode of server.c, which goes back to what
it was. It keeps the document contract, the runtime core (a work slot per
connection, the payload budget, core-owned ingress, borrowed PUT replies)
and the group commits, and adds what server.c lacked: HTTP/1.1 persistent
connections with in-order pipelining, an edge-triggered epoll owner
thread, up to 1,024 connections allocated as they arrive and reused, one
writev per answer, and documents opened through a store handle.

On the Pi 5 with one thread it serves 106k small keep-alive reads per
second (axum on three cores: 126k) at the same p99, 1,741 1 MiB reads
(axum: 1,370), and 1,126 durable writes from 64 connections (crash-safe
axum: 372), in 7.3 MiB against axum's 17-20 MiB. Note 075 has the table.

</content>
</entry>
</feed>
