PerlDancer/Dancer — pull request #1092 by snakpak (2014-11-22 20:18:21+00:00)
Title: 2000% speedup for large uploads

On large POSTs (think cellphone pics), there are a LOT of calls to add() since the reads from tmpfile come back in 8k blocks.

The worst part is that inside add(), in HTTP::Body::MultiPart::parse_boundary(), it runs an index() across the entire buffer (not just the addition) looking for MIME boundaries. So the on first pass it checks against 8k, the second against 16k, and the third against 24k, etc.

By the time your upload makes it to a couple megs, you've burned through a lot of CPU and can forget about scaling beyond one or two instances.

In testing I was trying to run 16 Starman/Dancer's behind Nginx and sending 16 copies of about 1.5MB jpeg's from another machine with ab. Total run time was originally about 12.5 seconds. After this one change, total run time is ~0.75 seconds. On larger batches of 1000 total requests by 16 concurrent, requests per second jumped from 1.2 to 24.9 and run time dropped from 780 seconds to 40.

Personally, I'm happy happy! :-) It looks like Dancer2 has the same problem though!