<!-- Source: https://medius.k4tech.net/comparison/control-link -->
# Control link

How fast each box replies to a query, how many moves it accepts (paced or clumped), and what it does with malformed input.

## Query round trip

A program sent each box 3,000 queries one at a time, in two runs, timed on the PC's USB bus.

#### Query round trip, p50

| Query | Stock | Medius | Result |
| --- | --- | --- | --- |
| Versionkm.version against QUERY(VERSION) | 177-184 µs | 219 µs | Stock |
| Statuskm.moving against QUERY(HEALTH) | 176-177 µs | 166 µs | Medius |

#### Query round trip, p95

| Query | Stock | Medius | Result |
| --- | --- | --- | --- |
| Versionkm.version against QUERY(VERSION) | 240 µs | 291-293 µs | Stock |
| Statuskm.moving against QUERY(HEALTH) | 234-235 µs | 230-239 µs | Equal |

## Paced moves, mouse still

One-count moves at a steady rate into a still mouse: stock's binary and text forms against Medius's MOVE frames, sent in 1 ms batches unless the table says otherwise. Each count adds 1 to the clone's X.

#### Counts arriving from 1 s of moves, binary

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 500/s | 500/500 | 500/500 | Equal |
| 1,000/s | 1,000/1,000 | 1,000/1,000 | Equal |
| 1,500/s | 1,500/1,500 | 1,500/1,500 | Equal |
| 2,000/s | 2,000/2,000 | 2,000/2,000 | Equal |
| 5,000/s | 5,000/5,000 | 5,000/5,000 | Equal |

#### Counts arriving from 1 s of moves, text

Stock `km.move`Medius `MOVE`

| Moves/s | Stock`km.move` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 500/s | 500/500 | 500/500 | Equal |
| 1,000/s | 1,000/1,000 | 1,000/1,000 | Equal |
| 1,500/s | 1,500/1,500 | 1,500/1,500 | Equal |
| 2,000/s | 2,000/2,000 | 2,000/2,000 | Equal |
| 5,000/s | 5,000/5,000 | 5,000/5,000 | Equal |

#### Counts arriving from 1 s of moves, one move per write

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 1,000/s | 1,000/1,000 | 1,000/1,000 | Equal |
| 2,000/s | 2,000/2,000 | 2,000/2,000 | Equal |
| 5,000/s | 5,000/5,000 | 5,000/5,000 | Equal |

#### Counts arriving from 5 s of moves, binary

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 250/s | 1,250/1,250 | 1,250/1,250 | Equal |
| 500/s | 5,000/5,000 | 5,000/5,000 | Equal |
| 1,000/s | 5,000/5,000 | 5,000/5,000 | Equal |
| 2,000/s | 10,000/10,000 | 10,000/10,000 | Equal |

#### Counts arriving from 5 s of moves, text

Stock `km.move`Medius `MOVE`

| Moves/s | Stock`km.move` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 250/s | 1,250/1,250 | 1,250/1,250 | Equal |
| 500/s | 5,000/5,000 | 5,000/5,000 | Equal |
| 1,000/s | 5,000/5,000 | 5,000/5,000 | Equal |
| 2,000/s | 10,000/10,000 | 10,000/10,000 | Equal |

## Paced moves, mouse moving

The same moves into a 1 kHz mouse whose Y moves 1-10 and back every 200 ms. Here stock refuses some moves, replying DE AD 01 00 18 FF to a binary move and ERR to a text one.

#### Counts arriving from 1 s of moves, binary

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 125/s | 125/125 | 125/125 | Equal |
| 500/s | 500/500 | 500/500 | Equal |
| 1,000/s | 999/1,000 | 1,000/1,000 | Medius |
| 1,500/s | 1,498/1,500 | 1,500/1,500 | Medius |
| 2,000/s | 1,966/2,000 | 2,000/2,000 | Medius |
| 3,000/s | 2,093/3,000 | 3,000/3,000 | Medius |
| 5,000/s | 2,095/5,000 | 5,000/5,000 | Medius |

#### Counts arriving from 1 s of moves, text

Stock `km.move`Medius `MOVE`

| Moves/s | Stock`km.move` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 125/s | 124/125 | 125/125 | Medius |
| 500/s | 500/500 | 500/500 | Equal |
| 1,000/s | 1,000/1,000 | 1,000/1,000 | Equal |
| 1,500/s | 1,500/1,500 | 1,500/1,500 | Equal |
| 2,000/s | 1,999/2,000 | 2,000/2,000 | Medius |
| 3,000/s | 1,962/3,000 | 3,000/3,000 | Medius |
| 5,000/s | 2,089/5,000 | 5,000/5,000 | Medius |

#### Counts arriving from 1 s of moves, one move per write

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 1,000/s | 999/1,000 | 1,000/1,000 | Medius |
| 2,000/s | 1,963/2,000 | 2,000/2,000 | Medius |
| 5,000/s | 2,023/5,000 | 5,000/5,000 | Medius |

#### Counts arriving from 5 s of moves, binary

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 125/s | 625/625 | 625/625 | Equal |
| 250/s | 1,249/1,250 | 1,250/1,250 | Medius |
| 500/s | 4,998/5,000 | 5,000/5,000 | Medius |
| 1,000/s | 4,997/5,000 | 5,000/5,000 | Medius |

#### Counts arriving from 5 s of moves, text

Stock `km.move`Medius `MOVE`

| Moves/s | Stock`km.move` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 125/s | 625/625 | 625/625 | Equal |
| 250/s | 1,250/1,250 | 1,250/1,250 | Equal |
| 500/s | 5,000/5,000 | 5,000/5,000 | Equal |
| 1,000/s | 4,997/5,000 | 5,000/5,000 | Medius |

## Move size

Moves of 10, 100 and 1,000 counts each, paced in 1 ms batches for 1 s into a still mouse.

#### Counts arriving from 1 s of 10-count moves, binary

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 500/s | 5,000/5,000 | 5,000/5,000 | Equal |
| 1,000/s | 10,000/10,000 | 10,000/10,000 | Equal |
| 1,500/s | 15,000/15,000 | 15,000/15,000 | Equal |
| 2,000/s | 20,000/20,000 | 20,000/20,000 | Equal |
| 5,000/s | 50,000/50,000 | 50,000/50,000 | Equal |

#### Counts arriving from 1 s of 100-count moves, binary

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 500/s | 50,000/50,000 | 50,000/50,000 | Equal |
| 1,000/s | 100,000/100,000 | 100,000/100,000 | Equal |
| 1,500/s | 150,000/150,000 | 150,000/150,000 | Equal |
| 2,000/s | 200,000/200,000 | 200,000/200,000 | Equal |
| 5,000/s | 500,000/500,000 | 500,000/500,000 | Equal |

#### Counts arriving from 1 s of 1,000-count moves, binary

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 500/s | 500,000/500,000 | 500,000/500,000 | Equal |
| 1,000/s | 1,000,000/1,000,000 | 1,000,000/1,000,000 | Equal |
| 1,500/s | 1,500,000/1,500,000 | 1,500,000/1,500,000 | Equal |
| 2,000/s | 2,000,000/2,000,000 | 2,000,000/2,000,000 | Equal |
| 5,000/s | 5,000,000/5,000,000 | 5,000,000/5,000,000 | Equal |

#### Counts arriving from 1 s of 10-count moves, text

Stock `km.move`Medius `MOVE`

| Moves/s | Stock`km.move` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 500/s | 5,000/5,000 | 5,000/5,000 | Equal |
| 1,000/s | 10,000/10,000 | 10,000/10,000 | Equal |
| 1,500/s | 15,000/15,000 | 15,000/15,000 | Equal |
| 2,000/s | 20,000/20,000 | 20,000/20,000 | Equal |
| 5,000/s | 50,000/50,000 | 50,000/50,000 | Equal |

#### Counts arriving from 1 s of 100-count moves, text

Stock `km.move`Medius `MOVE`

| Moves/s | Stock`km.move` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 500/s | 50,000/50,000 | 50,000/50,000 | Equal |
| 1,000/s | 100,000/100,000 | 100,000/100,000 | Equal |
| 1,500/s | 150,000/150,000 | 150,000/150,000 | Equal |
| 2,000/s | 200,000/200,000 | 200,000/200,000 | Equal |
| 5,000/s | 500,000/500,000 | 500,000/500,000 | Equal |

#### Counts arriving from 1 s of 1,000-count moves, text

Stock `km.move`Medius `MOVE`

| Moves/s | Stock`km.move` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 500/s | 500,000/500,000 | 500,000/500,000 | Equal |
| 1,000/s | 1,000,000/1,000,000 | 1,000,000/1,000,000 | Equal |
| 1,500/s | 1,500,000/1,500,000 | 1,500,000/1,500,000 | Equal |
| 2,000/s | 2,000,000/2,000,000 | 2,000,000/2,000,000 | Equal |
| 5,000/s | 5,000,000/5,000,000 | 5,000,000/5,000,000 | Equal |

## Moves in one write

One write holding a clump of one-count moves, then 100 more paced 1 ms apart. Stock's binary moves are 9 bytes, its text moves 14, Medius's frames 12.

#### Counts arriving from one write of moves, binary

Stock `MOVE (0x18)`Medius `MOVE`

| Moves in the write | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 8 | 8/8 | 8/8 | Equal |
| 16 | 16/16 | 16/16 | Equal |
| 20 | 20/20 | 20/20 | Equal |
| 24 | 24/24 | 24/24 | Equal |
| 28 | 56/56 | 56/56 | Equal |
| 29 | 58/58 | 58/58 | Equal |
| 30 | 29/60 | 60/60 | Medius |

#### Counts arriving from one write of moves, text

Stock `km.move`Medius `MOVE`

| Moves in the write | Stock`km.move` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 8 | 8/8 | 8/8 | Equal |
| 16 | 16/16 | 16/16 | Equal |

#### Parser after one write of 30 binary moves

Stock `MOVE (0x18)`Medius `MOVE`

| Write | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 30 moves, 270 bytes for stock | One command behind until a power cycle | In step | Medius[Stock defect](/comparison/defect-link-stock-parser-jam.md) |

## Fast paced moves

One-count moves paced in 1 ms batches for 2 s into a still mouse: stock's binary form at each rate and its text form at 8,000/s, against Medius at the same rates. Stock was power-cycled after each run that left its parser one command behind.

#### Counts arriving from 2 s of fast moves

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 5,000 | 20,000/20,000 | 20,000/20,000 | Equal |
| 7,000 | 28,000/28,000 | 28,000/28,000 | Equal |
| 10,000 | 39,982/40,000 | 40,000/40,000 | Medius |
| 15,000 | 26,805/30,000 | 30,000/30,000 | Medius |
| 20,000 | 26,577/40,000 | 40,000/40,000 | Medius |

#### Counts arriving from 2 s of text moves at 8,000/s

Stock `km.move`Medius `MOVE`

| Runs | Stock`km.move` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 8,000/s | 96,000/96,000 | 96,000/96,000 | Equal |

## Clumped and back-to-back writes

One-count binary moves into a still mouse, written in clumps every 16 ms (as a sender whose timer wakes every 16 ms writes them), or 12,871 back to back in 4,096-byte writes. Stock was power-cycled after each run that left its parser one command behind.

#### Counts arriving from moves written in clumps every 16 ms

Stock `MOVE (0x18)`Medius `MOVE`

| Moves/s | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 1,000/s, 16 per write | 1,000/1,000 | 1,000/1,000 | Equal |
| 2,000/s, 32 per write | 92/2,000 | 2,000/2,000 | Medius |

#### Counts arriving from 12,871 moves written back to back

Stock `MOVE (0x18)`Medius `MOVE`

| Write | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 4,096-byte writes | 138/12,871 | 12,871/12,871 | Medius |

#### Parser afterwards

Stock `MOVE (0x18)`Medius `MOVE`

| Write | Stock`MOVE (0x18)` | Medius`MOVE` | Result |
| --- | --- | --- | --- |
| 2,000/s, 32 per write | One command behind until a power cycle | In step | Medius |
| 12,871 moves back to back | One command behind until a power cycle | In step | Medius |

## Malformed input

Malformed input sent to each box, then a valid move. One try each.

#### Valid move after the malformed input

Stock `km.move`Medius `MOVE(NOW)`

| Malformed input | Stock`km.move` | Medius`MOVE(NOW)` | Result |
| --- | --- | --- | --- |
| 64 KB of random bytes | Arrives | Arrives | Equal |
| Half a move, the valid move 100 ms later | Lost | Arrives | Medius |
| Half a move, the valid move straight after | Lost | Lost | Equal |
| Move with a length field too long | Lost | Arrives | Medius |
| Unknown command | Arrives | Arrives | Equal |
| Move too short | Arrives | Arrives | Equal |
| 5-count move with one bit flipped | Arrives | Arrives | Equal |
| Move written one byte a millisecond | Arrives | Arrives | Equal |
| 100 moves, a zero byte after each | Arrives | Arrives | Equal |

#### Counts moved by the malformed input

| Malformed input | Stock | Medius | Result |
| --- | --- | --- | --- |
| 64 KB of random bytes | 0 | 0 | Equal |
| Unknown command | 0 | 0 | Equal |
| Move too short | 0 | 0 | Equal |
| 5-count move with one bit flipped | 4 | 0 | Medius |

#### Replies to queries afterwards

| Check | Stock | Medius | Result |
| --- | --- | --- | --- |
| After each malformed input | Correct | Correct | Equal |
