displayProperties are set up with observers on each, one for each displayProperty. See core_foundation/views/view/statechart.js line 1095. contentDisplayProperties meanwhile are hooked up as a single * observer on the content item, which then checks each property change notification against the contentDisplayProperties list.
My hunch now that I think through it is that single-property observers are expensive to create, but cheap to operate going forward, whereas * property observers are cheap to create (since there can only be one), but expensive to operate going forward (since any property change triggers a scan). That means that for long-lived, relatively static views, displayProperties wins because you only do the setup once, while for fast-moving views (i.e. the canonical fast-scrolling-ListView example), the fast-to-setup * observer wins.