2009-04-01 11 views
40

Tôi đang sử dụng mô-đun json trong Python 2.6 để tải và giải mã các tệp JSON. Tuy nhiên tôi hiện đang nhận được chậm hơn so với hiệu suất dự kiến. Tôi đang sử dụng một trường hợp thử nghiệm có kích thước 6MB và json.loads() mất 20 giây.Hiệu suất giải mã JSON JSON

Tôi nghĩ mô-đun json có một số mã gốc để tăng tốc độ giải mã?

Làm cách nào để kiểm tra xem điều này có đang được sử dụng không?

Để so sánh, tôi đã tải xuống và cài đặt mô-đun python-cjsoncjson.decode() mất 1 giây cho cùng một trường hợp thử nghiệm.

Tôi muốn sử dụng mô-đun JSON được cung cấp với Python 2.6 để người dùng mã của tôi không bắt buộc phải cài đặt các mô-đun bổ sung.

(Tôi đang phát triển trên Mac OS X, nhưng tôi nhận được một kết quả tương tự trên Windows XP.)

+1

Điều này được giải quyết bằng Python 2.7, mỗi số so sánh từ [Tomas] (http://stackoverflow.com/users/362757/tomas), Ivo, TONy.W bên dưới. Tagged này python-2.6 – smci

+0

(Mỗi số TONy.W, vấn đề duy nhất còn lại là stdlib json ** mã hóa ** vẫn còn 2x chậm hơn trong 2,7) – smci

Trả lời

18

Nó có thể thay đổi theo nền tảng, nhưng mô-đun json dựng sẵn dựa trên simplejson, không bao gồm tăng tốc C. Tôi đã tìm thấy simplejson để được nhanh như python-cjson anyway, vì vậy tôi thích nó vì nó rõ ràng có giao diện tương tự như nội trang.

try: 
    import simplejson as json 
except ImportError: 
    import json 

Dường như với tôi đó là thành ngữ tốt nhất trong một thời gian, mang lại hiệu suất khi có sẵn trong khi tương thích về phía trước.

+0

fwiw, 11nov 2009 http://pypi.python.org/packages/source/s/simplejson/simplejson-2.0.9.tar.gz trên mac 10.4.11 ppc, gcc 4.2.1 => simplejson/_speedups.c: 2256: lỗi: định nghĩa lại 'PyTypeObject PyEncoderType' CẢNH BÁO: Không thể biên dịch phần mở rộng C, tăng tốc không được bật. – denis

+1

Nếu 'py-yajil' và' ultrajson' nhanh hơn, lợi thế của việc sử dụng 'simplejson' ngoài việc trông giống như' json' và thuần túy là Python là gì? –

+0

@Shurane không phải 'py-yajl' cũng không' superjson' hỗ trợ tất cả các đối số mà 'json' làm. 'simplejson' nhanh hơn' json' (do tăng tốc C) và thay thế drop-in. –

2

Nhìn trong cài đặt của tôi về Python 2.6.1 trên cửa sổ, gói json nạp module _json, mà được xây dựng trong thời gian chạy. C nguồn cho mô-đun json speedupshere.

>>> import _json 
>>> _json 
<module '_json' (built-in)> 
>>> print _json.__doc__ 
json speedups 
>>> dir(_json) 
['__doc__', '__name__', '__package__', 'encode_basestring_ascii', 'scanstring'] 
>>> 
+0

Tôi cũng giả định rằng json với _json sẽ nhanh. Một điểm chuẩn chứng minh tôi sai. –

+1

Gói 'json' * sử dụng mô-đun' _json' C * trong mui xe * đã *. Có rất ít sử dụng trong việc truy cập trực tiếp. –

1

Mặc dù _json khả dụng, tôi đã nhận thấy giải mã json rất chậm trên CPython 2.6.6. Tôi đã không so sánh với các triển khai khác, nhưng tôi đã chuyển sang thao tác chuỗi khi bên trong các vòng lặp hiệu suất quan trọng.

24

Yajl - Yet Another JSON Library mới rất nhanh.

yajl  serialize: 0.180 deserialize: 0.182 total: 0.362 
simplejson serialize: 0.840 deserialize: 0.490 total: 1.331 
stdlib json serialize: 2.812 deserialize: 8.725 total: 11.537 

Bạn có thể compare the libraries yourself.

Cập nhật:UltraJSON thậm chí còn nhanh hơn.

+1

Cảm ơn bạn đã liên kết với ujson;) Nó cho tôi thêm 400 req/giây trên dịch vụ tìm kiếm gevent/redis của tôi. – Justin

+0

Tôi đã thử nghiệm bản thân mình và có kết quả rất cạnh tranh. Không tăng tốc 20 lần. Sử dụng kịch bản so sánh (từ liên kết được cung cấp) và JSON lớn (20MB) - vẫn có hiệu suất rất so sánh. – Tomas

16

Tôi đã phân tích cú pháp cùng một tệp 10x. Kích thước tệp là 1,856,944 byte.

Python 2.6:

yajl  serialize: 0.294 deserialize: 0.334 total: 0.627 
cjson  serialize: 0.494 deserialize: 0.276 total: 0.769 
simplejson serialize: 0.554 deserialize: 0.268 total: 0.823 
stdlib json serialize: 3.917 deserialize: 17.508 total: 21.425 

Python 2.7:

yajl  serialize: 0.289 deserialize: 0.312 total: 0.601 
cjson  serialize: 0.232 deserialize: 0.254 total: 0.486 
simplejson serialize: 0.288 deserialize: 0.253 total: 0.540 
stdlib json serialize: 0.273 deserialize: 0.256 total: 0.528 

Không chắc lý do tại sao con số này là không cân xứng từ kết quả của bạn. Tôi đoán, các thư viện mới hơn?

+1

Tôi cũng nhận thấy sự khác biệt hiệu suất đáng kể của stdlib (tức là được xây dựng trong) json giữa python 2,6 và 2,7. Vì vậy, đó là một lý do tại sao python 2.7 được ưa thích hơn 2.6. – RayLuo

+4

Lý do rất đơn giản: Tốc độ C cho json được thêm vào trong Python 2.7. Từ ghi chú phát hành: "Mô-đun cập nhật: Mô-đun json đã được nâng cấp lên phiên bản 2.0.9 của gói simplejson, bao gồm phần mở rộng C giúp mã hóa và giải mã nhanh hơn. "Http://docs.python.org/dev/whatsnew/2.7.html –

+2

+1 Số vô cùng quý giá Tomas. Vì vậy, 2,7 khắc phục mọi thứ. – smci

13

hãy xem UltraJSON https://github.com/esnme/ultrajson

đây thử nghiệm của tôi (mã từ: https://gist.github.com/lightcatcher/1136415)

nền tảng: OS X 10.8.3 MBP 2.2 GHz Intel Core i7

JSON:

simplejson == 3.1.0

python-cjson == 1.0.5

jsonlib == 1.6.1

ujson == 1.30

yajl == 0.3.5

JSON Benchmark 
2.7.2 (default, Oct 11 2012, 20:14:37) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] 
----------------------------- 
ENCODING 
simplejson: 0.293394s 
cjson: 0.461517s 
ujson: 0.222278s 
jsonlib: 0.428641s 
json: 0.759091s 
yajl: 0.388836s 

DECODING 
simplejson: 0.556367s 
cjson: 0.42649s 
ujson: 0.212396s 
jsonlib: 0.265861s 
json: 0.365553s 
yajl: 0.361718s 
+1

Tính đến tháng 8 năm 2014, những kết quả này chủ yếu là chính xác trên các phiên bản thư viện mới nhất.) cạnh cjson là khoảng x2 simplejson và 3x json, hiệu suất cjson cũng khá không ổn định trên các bộ dữ liệu cụ thể, vì vậy chúng tôi đang gắn bó với ujson. –

2

Đối với những người đang phân tích đầu ra từ một yêu cầu sử dụng các gói yêu cầu, ví dụ:

res = requests.request(...) 

text = json.loads(res.text) 

Điều này có thể rất chậm đối với nội dung phản hồi lớn hơn, nói ~ 45 giây cho 6 MB trên MacBook 2017 của tôi. Nó không được gây ra bởi một trình phân tích cú pháp json chậm, mà thay vào đó là do xác định tập hợp ký tự chậm bằng cuộc gọi res.text.

Bạn có thể giải quyết việc này bằng cách thiết lập các ký tự đặt trước bạn đang gọi res.text, và sử dụng các gói cchardet (xem thêm here):

if res.encoding is None: 
    res.encoding = cchardet.detect(res.content)['encoding'] 

Điều này làm cho json văn bản phản ứng phân tích gần như ngay lập tức !