2017-01-22 5 views
2

나는 거대한 json 응답을주는 웹 서비스를 가지고있다. 여기서는 iPython 코드 스 니펫을 제공합니다.내장 된 JSON 빌더가 명시 적 JSON 로더와 비교하여 더 빨리 실행되는 이유는 무엇입니까?

In [1]: import requests 

In [2]: r = requests.post("<API endpoint>", data={"number_of_row" : 10000000}) 

In [3]: r 
Out[3]: <Response [200]> 

In [4]: import json 

In [5]: %timeit json.loads(r.text) 
1 loop, best of 3: 36.5 s per loop 

In [6]: %timeit r.json() 
10 loops, best of 3: 121 ms per loop 

유청 5 호는 6 호에 비해 시간이 오래 걸립니까? 궁극적으로 JSON 객체를받은 응답 데이터에서 제외시키고 싶습니다.

편집 # 1 : simplejson과 함께 통계를 추가하고 구문 분석을 되돌릴 수 있습니다. 주의 할

In [11]: r = requests.post("<API endpoint>", data={"number_of_row": 10000000}) 

In [12]: res = requests.post("<API endppoint>", data={"number_of_row": 10000000}) 

In [13]: %timeit r.json() 
10 loops, best of 3: 120 ms per loop 

In [14]: %timeit res.json() 
10 loops, best of 3: 120 ms per loop 

In [15]: %timeit json.loads(r.text) 
1 loop, best of 3: 36.5 s per loop 

In [16]: %timeit simplejson.loads(r.text) 
1 loop, best of 3: 36.3 s per loop 

그리고 한 가지, 어디서든 구현에는 caching이 없습니다. API 엔드 포인트가 내 통제하에 있습니다.

편집 # 2 :

In [18]: %timeit json.loads(r.content.decode(requests.utils.guess_json_utf(r.content))) 
10 loops, best of 3: 119 ms per loop 

In [19]: %timeit r.json() 
10 loops, best of 3: 63.3 ms per loop 

In [20]: %timeit json.loads(r.text) 
1 loop, best of 3: 36.5 s per loop 

답변

0

requests.models.Response.json()이 interally json.loads (또는 simplejson.loads)를 사용합니다. 따라서 simplejson을 설치하지 않으면 차이가 없어야합니다.

시간차가 네트워크 IO에서 비롯된 것 같습니다. 데이터를 가져 오면 캐시됩니다. 따라서 두 번째 캐시 (r.json)는 캐시 된 데이터를 사용합니다. 시간이 좀 걸리지.

통화 순서를 바꾸면 취소됩니다. requests.models.Response.json()requests.utils.guess_json_utf 사용하면서 EDIT

request.models.Response.text

utf-8, utf-16, utf-32는 JSON의 RFC에 따른 4627 부 (3)

In [1]: content = 'a' * 1000000000 

In [2]: import chardet 

In [3]: %timeit chardet.detect(content)['encoding'] 
1 loops, best of 3: 9.6 s per loop 

In [4]: import requests.utils 

In [5]: %timeit requests.utils.guess_json_utf(content) 
1000000 loops, best of 3: 835 ns per loop 
+0

I가 의심 고려하는 응답의 인코딩을 추측 chardet.detect 사용 n/w IO입니다. 왜냐하면 내가 응답을 파싱 할 때, n/w 입출력은 이미 끝났기 때문이다. 그것은 순수한 구문 분석 논리입니다. 또한, 역 분개 파싱 방법을 사용하여 내 질문을 편집했습니다. 확인하십시오. –

+0

@AashishP, 이상 하네. BTW, 캐싱 나는'요청'측면 에서이 아니라 서버 쪽에서 의미. – falsetru

+0

@AashishP,'json.loads (r.content.decode (requests.utils.guess_json_utf (r.content)))'시간을 정할 수 있습니까? 'Response.text'는 가능한 모든 인코딩을 고려한'chardet'을 사용하여 인코딩을 탐지하려고 시도하며,'Response.json'은 utf-8, utf-16, utf-32 만 고려하는'guess_json_utf'를 사용합니다. – falsetru