There are 5 different slightly different situations in which bzr update can be used:
Should be O(1) to determine Tree base is up to date wt.last-rev == wt.b.last-rev
2/3 could be concurrent (but that may not necessarily be faster)
potential issue w/ serialized is having 50k files in limbo/
the limbo/ directory could be avoided in some cases, for example when adding new files in new directories.
modifying in place: reduces fragmentation of fs, not atomic w/ local modification, potential of data loss w/o should be safe
"local mod" is diff between disk and last commit, not merge base
Detecting name conflicts should be O(siblings). Alternatively, conflicts with existing files can be detected using stat() and conflicts with new files can be detected by examining the pending transform. This changes complexity to O(changes).
offtopic: should bzr update report where the source is ? should bzr update handle both cases (local tree out-of-date w/local branch, checkout out-of-date w/master) ?
if updating would diverge, give opportuniuty to branch/unbind instead local ahead, "push to master"
ideas: 1) can this be done as a single logical step? 2) can this be done w/o modifying working tree until end? possible performance improvements 3) if the pulling revision step could deliver full texts, that may help for the merge (same thing as "bzr pull")