The problem isn't with disk IO as much as it's with speed of the stat() syscall. IIRC Cygwin stat() is backed by three different NT syscalls, so it's slow because it requires three transitions to kernel mode, where Linux only needs one. Setting core.fileMode to false makes Git use a Windows optimized version of stat(), so it runs a lot faster.
Unfortunately it's still not quite as fast as on Linux and OS X, but it's about as fast as native/MSYS versions of Git on Windows.
It's not the number of "transitions to kernel mode" (which is actually really fast), but the cost of performing the UID mapping, especially considering that this effort is frequently wasted when programs don't bother inspecting st_uid and friends. That's why I wish the Linux xstat syscall, the one that let programs ask for just what they need, had gone through: it'd have made other systems more efficient too.
MsysGit is still way slower than Git on Linux, at least on larger repositories. Calling stat() on lots of small files is pretty much a worst-case scenario for NTFS.