Skip to content

Commit 9a2f4a8

Browse files
committed
Encode json more compactly.
Optimise json by attempting in the following order: - using C simplejson module (faster than baseline by 3x) - using python's built in json module (faster than baseline by 2x) if both fail use pure Python embedded simplejson (baseline).
1 parent efc8b78 commit 9a2f4a8

File tree

9 files changed

+50
-13
lines changed

9 files changed

+50
-13
lines changed

bin/dependencies_b.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ def check_dependencies():
1616

1717
check_twisted()
1818
check_win32()
19+
i+=check_json()
1920
i+=check_java()
2021
i+=check_hg()
2122

@@ -99,7 +100,16 @@ def twisted_fail(x, y=None):
99100
import twisted.words
100101
except ImportError:
101102
twisted_fail("words")
102-
103+
104+
def check_json():
105+
import qwebirc.util.qjson
106+
if qwebirc.util.qjson.slow:
107+
warn("simplejson module with C speedups not installed.",
108+
"using embedded module (slower); consider installing simplejson from:",
109+
"http://pypi.python.org/pypi/simplejson/")
110+
return 1
111+
return 0
112+
103113
if __name__ == "__main__":
104114
import dependencies
105115
dependencies.check_dependencies()

bin/mkstatic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def main():
6464

6565
compile.main(DEST, produce_debug=False)
6666

67-
for x in "authgate qwebirc simplejson twisted".split(" "):
67+
for x in "authgate qwebirc esimplejson twisted".split(" "):
6868
copypydir(x, DEST)
6969
for x in "images panes sound".split(" "):
7070
copydir(os.path.join("static", x), DEST)

bin/optionsgen.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import config, simplejson
1+
import config
2+
import qwebirc.util.qjson as json
23

34
def get_options():
45
options = dict(networkName=config.NETWORK_NAME, networkServices=[config.AUTH_SERVICE], loginRegex=config. AUTH_OK_REGEX, appTitle=config.APP_TITLE, baseURL=config.BASE_URL)
5-
return simplejson.dumps(options)
6+
return json.dumps(options)

simplejson/__init__.py renamed to esimplejson/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@
106106
]
107107

108108
if __name__ == '__main__':
109-
from simplejson.decoder import JSONDecoder
110-
from simplejson.encoder import JSONEncoder
109+
from esimplejson.decoder import JSONDecoder
110+
from esimplejson.encoder import JSONEncoder
111111
else:
112112
from decoder import JSONDecoder
113113
from encoder import JSONEncoder

simplejson/decoder.py renamed to esimplejson/decoder.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import re
55
import sys
66

7-
from simplejson.scanner import Scanner, pattern
7+
from esimplejson.scanner import Scanner, pattern
88
try:
9-
from simplejson._speedups import scanstring as c_scanstring
9+
from esimplejson._speedups import scanstring as c_scanstring
1010
except ImportError:
1111
pass
1212

simplejson/encoder.py renamed to esimplejson/encoder.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import re
55

66
try:
7-
from simplejson._speedups import encode_basestring_ascii as c_encode_basestring_ascii
7+
from esimplejson._speedups import encode_basestring_ascii as c_encode_basestring_ascii
88
except ImportError:
99
pass
1010

File renamed without changes.

qwebirc/engines/ajaxengine.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
from twisted.names import client
33
from twisted.internet import reactor, error
44
from authgateengine import login_optional, getSessionData
5-
import simplejson, md5, sys, os, time, config, qwebirc.config_options as config_options, traceback, socket
5+
import md5, sys, os, time, config, qwebirc.config_options as config_options, traceback, socket
66
import qwebirc.ircclient as ircclient
77
from adminengine import AdminEngineAction
88
from qwebirc.util import HitCounter
99
import qwebirc.dns as qdns
10+
import qwebirc.util.qjson as json
1011
Sessions = {}
1112

1213
def get_session_id():
@@ -25,6 +26,7 @@ class PassthruException(Exception):
2526
pass
2627

2728
NOT_DONE_YET = None
29+
EMPTY_JSON_LIST = json.dumps([])
2830

2931
def jsondump(fn):
3032
def decorator(*args, **kwargs):
@@ -38,7 +40,7 @@ def decorator(*args, **kwargs):
3840
except PassthruException, e:
3941
return str(e)
4042

41-
return simplejson.dumps(x)
43+
return json.dumps(x)
4244
return decorator
4345

4446
def cleanupSession(id):
@@ -79,7 +81,7 @@ def timeout(self, channel):
7981
if self.schedule:
8082
return
8183

82-
channel.write(simplejson.dumps([]))
84+
channel.write(EMPTY_JSON_LIST)
8385
if channel in self.subscriptions:
8486
self.subscriptions.remove(channel)
8587

@@ -105,7 +107,7 @@ def flush(self, scheduled=False):
105107

106108
self.throttle = t + config.UPDATE_FREQ
107109

108-
encdata = simplejson.dumps(self.buffer)
110+
encdata = json.dumps(self.buffer)
109111
self.buffer = []
110112
self.buflen = 0
111113

qwebirc/util/qjson.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
slow = True
2+
try:
3+
# first try the system module
4+
import simplejson as json
5+
try:
6+
# try to see if the C module is available
7+
json._speedups
8+
except AttributeError:
9+
pass
10+
else:
11+
slow = False
12+
except ImportError:
13+
# try python 2.6's json library as
14+
# it is 2x as fast as simplejson with no C
15+
try:
16+
import json
17+
json.dumps # we don't want the silly third party version
18+
except (ImportError, AttributeError):
19+
# fallback to the embedded
20+
import esimplejson as json
21+
22+
__SEPS = (',', ':')
23+
dumps = lambda x: json.dumps(x, encoding="utf8", ensure_ascii=True, check_circular=False, indent=None, separators=__SEPS)
24+
loads = lambda x: json.loads(x, encoding="utf8")

0 commit comments

Comments
 (0)