2015-01-02 15 views
8

tôi đã thực hiện một trường hợp thử nghiệm nhỏ để so sánh YAML và JSON tốc độ:Tôi có thể tăng tốc YAML không?

import json 
import yaml 
from datetime import datetime 
from random import randint 

NB_ROW=1024 

print 'Does yaml is using libyaml ? ',yaml.__with_libyaml__ and 'yes' or 'no' 

dummy_data = [ { 'dummy_key_A_%s' % i: i, 'dummy_key_B_%s' % i: i } for i in xrange(NB_ROW) ] 


with open('perf_json_yaml.yaml','w') as fh: 
    t1 = datetime.now() 
    yaml.safe_dump(dummy_data, fh, encoding='utf-8', default_flow_style=False) 
    t2 = datetime.now() 
    dty = (t2 - t1).total_seconds() 
    print 'Dumping %s row into a yaml file : %s' % (NB_ROW,dty) 

with open('perf_json_yaml.json','w') as fh: 
    t1 = datetime.now() 
    json.dump(dummy_data,fh) 
    t2 = datetime.now() 
    dtj = (t2 - t1).total_seconds() 
    print 'Dumping %s row into a json file : %s' % (NB_ROW,dtj) 

print "json is %dx faster for dumping" % (dty/dtj) 

with open('perf_json_yaml.yaml') as fh: 
    t1 = datetime.now() 
    data = yaml.safe_load(fh) 
    t2 = datetime.now() 
    dty = (t2 - t1).total_seconds() 
    print 'Loading %s row from a yaml file : %s' % (NB_ROW,dty) 

with open('perf_json_yaml.json') as fh: 
    t1 = datetime.now() 
    data = json.load(fh) 
    t2 = datetime.now() 
    dtj = (t2 - t1).total_seconds() 
    print 'Loading %s row into from json file : %s' % (NB_ROW,dtj) 

print "json is %dx faster for loading" % (dty/dtj) 

Và kết quả là:

Does yaml is using libyaml ? yes 
Dumping 1024 row into a yaml file : 0.251139 
Dumping 1024 row into a json file : 0.007725 
json is 32x faster for dumping 
Loading 1024 row from a yaml file : 0.401224 
Loading 1024 row into from json file : 0.001793 
json is 223x faster for loading 

Tôi đang sử dụng PyYAML 3.11 với thư viện libyaml C trên ubuntu 12.04. Tôi biết rằng json đơn giản hơn nhiều so với yaml, nhưng với tỷ lệ 223x giữa json và yaml tôi tự hỏi liệu cấu hình của tôi có đúng hay không.

Bạn có cùng tỷ lệ tốc độ không?
Làm cách nào để tăng tốc độ yaml.load()?

Trả lời

12

Bạn có thể nhận thấy cú pháp của Python cho cấu trúc dữ liệu là rất tương tự cú pháp của JSON.

gì đang xảy ra là thư viện json Python của mã hóa kiểu dữ liệu dựng sẵn Python của directly into text chunks, thay thế ' vào " và xóa , ở đây và ở đó (để đơn giản hóa một chút). Mặt khác, pyyaml phải construct a whole representation graph trước khi nối tiếp nó thành một chuỗi.

Cùng một loại công cụ phải xảy ra ngược khi tải.

Cách duy nhất để tăng tốc yaml.load() sẽ được để viết một mới Loader, nhưng tôi nghi ngờ nó có thể là một bước nhảy vọt lớn trong hoạt động, trừ khi bạn sẵn sàng để viết đơn mục đích riêng của bạn sắp xếp của YAML phân tích cú pháp, lấy the following comment trong việc xem xét:

YAML xây dựng một đồ thị vì nó là một mục đích chung serialization định dạng mà có thể đại diện cho nhiều tài liệu tham khảo để cùng một đối tượng . Nếu bạn không biết đối tượng nào được lặp lại và chỉ có các kiểu cơ bản xuất hiện, bạn có thể sử dụng một serialson json, nó sẽ vẫn là YAML hợp lệ.

- CẬP NHẬT

gì tôi đã nói trước vẫn đúng, nhưng nếu bạn đang chạy Linux có một cách để tăng tốc độ Yaml phân tích cú pháp. Theo mặc định, yaml của Python sử dụng trình phân tích cú pháp Python. Bạn phải nói rằng bạn muốn sử dụng trình phân tích cú pháp PyYamlC.

Bạn có thể làm theo cách này:

import yaml 
from yaml import CLoader as Loader, CDumper as Dumper 

dump = yaml.dump(dummy_data, fh, encoding='utf-8', default_flow_style=False, Dumper=Dumper) 
data = yaml.load(fh, Loader=Loader) 

Để làm như vậy, bạn cần yaml-cpp-dev cài đặt, ví dụ với apt-get:

$ apt-get install yaml-cpp-dev 

PyYaml với LibYaml là tốt. Nhưng đó là trường hợp dựa trên đầu ra của bạn.

Tôi không thể kiểm tra ngay bây giờ vì tôi đang chạy OS X và brew có một số sự cố khi cài đặt yaml-cpp-dev nhưng nếu bạn theo dõi PyYaml documentation, họ thấy rõ rằng hiệu suất sẽ tốt hơn nhiều.

+1

tải vẫn chậm hơn 12x với mẫu yaml.my là danh sách 600.000 từ điển trống. Yaml không cần phải làm bất cứ điều gì thêm ngoại trừ phân tích cú pháp một chút thông minh mà nên mất gần như không có thêm thời gian. – codeshot

+1

Trên mac: brew install yaml-cpp libyaml –

+0

Jivan bạn là một huyền thoại đẫm máu. Tôi sẽ viết lại một số mã python trong C++ để tăng tốc độ. Tập tin yaml 6MB của tôi mất 53 giây để tải bằng cách sử dụng bộ tải yaml tiêu chuẩn, và chỉ 3 giây với CLoader. – nevelis

0

Vâng, tôi cũng nhận thấy rằng JSON nhanh hơn. Vì vậy, một cách tiếp cận hợp lý sẽ là chuyển đổi YAML thành JSON trước. Nếu bạn không nhớ ruby, sau đó bạn có thể nhận được sự tăng tốc lớn và mương yaml cài đặt hoàn toàn:

import commands, json 
def load_yaml_file(fn): 
    ruby = "puts YAML.load_file('%s').to_json" % fn 
    j = commands.getstatusoutput('ruby -ryaml -rjson -e "%s"' % ruby) 
    return json.loads(j[1]) 

Dưới đây là một so sánh cho 100K hồ sơ:

load_yaml_file: 0.95 s 
yaml.load: 7.53 s 

Và đối với 1M hồ sơ:

load_yaml_file: 11.55 s 
yaml.load: 77.08 s 

Nếu bạn vẫn cứ sử dụng yaml.load, hãy nhớ đặt nó trong virtualenv để tránh xung đột với phần mềm khác.

Các vấn đề liên quan