This post helped me track down the issue. Thanks to wpunkts the true reason for the lag is brought to light:
Avoiding opening and closing a socket for every put is the key.
Now as of how to resolve it, I found that the bridgeclient.py already has an answer, but it's not obvious or well documented.
// Init a bridge client
client = bridgeclient()
// Flag it to not open and close the socket every function call
client.begin()
A quick peek at the source reveals that's what begin does. And indeed it appears to have the same performance as your json client, but for some reason my values weren't saved with that approach, and I'd like to trust the lib where I can.
Hope this helps some one else with this problem!