Skip to content
Tech News
← Back to articles

Premature Optimization Is Fun Sometimes

read original get Code Optimization Book → more articles

Premature Optimization is Fun Sometimes ↩︎ Home

A colleague of mine was recently discussing a connectivity monitoring system he is working on with me. It’s nothing fancy, just sending ICMP Echo Requests to a couple of different servers, and monitoring latency and dropped packet averages over 1-minute, 5-minute, and 15-minute periods. Up came the topic of how this data should be stored, the natural thought was a 512 entry ring buffer, containing entries like the following:

struct ping_timestamp { ping_timestamp uint64_t sent_ns ; // when the packed was sent (unit: ns) sent_ns uint64_t received_ns ; // when the packet was received (unit: ns) received_ns ; // source address in_addr_t source_addr uint16_t seq_no ; // echo request sequence number seq_no bool received ; // has the request been received? received };

And backed by the following array

struct ping_timestamp pings_rb [ 512 ]; ping_timestamp pings_rb // ... ( " %zu

" , sizeof ( pings_rb )); printfpings_rb // 12288

12 KiB. Pretty wasteful, right? We can certainly do better. Do we need to keep fields for both sent and received ? What we’re really interested is the latency. We need to know when a packet was sent, only up until we know when it was received, at that point, the data we want to keep is received - sent , so why don’t we make it a tagged union?

struct ping_timestamp_2 { ping_timestamp_2 union { uint64_t sent_ts ; // unit: 100μs sent_ts uint64_t elapsed_ts ; // unit: 100μs elapsed_ts }; ; in_addr_t source_addr uint16_t seq_no ; seq_no bool received ; received }; // ... ( " %zu

" , sizeof ( pings_rb )); printfpings_rb // 8192

Not bad, we’ve shaved off an entire page. We can still do better.

... continue reading