Ref T4189. When we write() a large buffer to an ExecFuture, the fwrite() loop currently looks like this:
$bytes_written = fwrite($socket, $buffer); $buffer = substr($buffer, $bytes_written);
This is normally fine, but substr() is approximately O(N) in the size of the new string, since it has to allocate and copy it.
Instead, add PhutilRope, which stores a string as a list of small buffers. This allows us to remove bytes from the beginning of the string very cheaply.
In particular, this can occur when you git push a very large repository. If we read off the network faster than we write to git receive-pack, we end up with a very large internal buffer which is expensive and slow to write through.