  We present highly optimized data structures for the dynamic predecessor
problem, where the task is to maintain a set $S$ of $w$-bit numbers under
insertions, deletions, and predecessor queries (return the largest element in
$S$ no larger than a given key). The problem of finding predecessors can be
viewed as a generalized form of the membership problem, or as a simple version
of the nearest neighbour problem. It lies at the core of various real-world
problems such as internet routing.
  In this work, we engineer (1) a simple implementation of the idea of universe
reduction, similar to van-Emde-Boas trees (2) variants of y-fast tries
[Willard, IPL'83], and (3) B-trees with different strategies for organizing the
keys contained in the nodes, including an implementation of dynamic fusion
nodes [P\v{a}tra\c{s}cu and Thorup, FOCS'14]. We implement our data structures
for $w=32,40,64$, which covers most typical scenarios.
  Our data structures finish workloads faster than previous approaches while
being significantly more space-efficient, e.g., they clearly outperform
standard implementations of the STL by finishing up to four times as fast using
less than a third of the memory. Our tests also provide more general insights
on data structure design, such as how small sets should be stored and handled
and if and when new CPU instructions such as advanced vector extensions pay
off.
