Looks to me like most of what you're measuring is open() and flock(); Try the comparison again using strings in memory. Also, XS isn't necessarily faster. You're only going to notice huge speedups if the code you're doing in C has a *lot* to do before it hands it back to perl. If most of the code is handing things to perl, it may (probably not, but possibly) even slow it down compared to just doing things natively.
You may notice ad hoc parsing of short strings is faster in native perl and JSON::XS is only faster for large-ish js inputs. I suspect JSON::XS is usually faster though. It really depends how much parsing your ad hoc format requires.