git-filter-branch always calls git-read-tree for each commit, even when
no modifications to the index are performed. Admittedly, read-tree is
not as costly an operation as checkout-index, but on a big repo, it is
not free either.
For example, I use Git to perform rolling backups of my home, with
daily/weekly/monthly branches. (At least, that's the plan.) After a
while, I reparent those branches to get rid of the oldest commits. This
should be quite snappy, but due to read-index processing 37000+ entries
for each commit, it's actually quite painful.