피클 또는 JSON?


114

dict키가 유형 str이고 값이 ints 인 작은 개체 를 디스크에 저장 한 다음 복구해야합니다 . 이 같은:

{'juanjo': 2, 'pedro':99, 'other': 333}

최선의 선택은 무엇이며 그 이유는 무엇입니까? pickle또는로 직렬화하십시오 simplejson.

Python 2.6을 사용하고 있습니다.


무엇으로 변환합니까? 또한 어떤 의미에서 더 나은가 ?
— SilentGhost 2010

10
2.6에서는를 사용하지 않고 simplejson내장 json모듈 (정확한 인터페이스가 동일 함)을 사용합니다.
— Mike Graham

5
"베스트"? 무엇에 가장 적합합니까? 속도? 복잡성? 적응성? 비용?
— S.Lott


답변:


68

상호 운용성 요구 사항이없고 (예 : Python에서 데이터를 사용하려는 경우) 바이너리 형식이 괜찮다면, 정말 빠른 Python 객체 직렬화를 제공 하는 cPickle 을 사용하십시오.

상호 운용성을 원하거나 텍스트 형식으로 데이터를 저장하려면 JSON (또는 제약 조건에 따라 다른 적절한 형식)을 사용하십시오.


48
JSON 은 cPickle보다 빠른 것 같습니다 .
— mac

5
내 대답은 두 솔루션 중 하나를 선택할 때 가장 중요하다고 생각하는 문제를 강조합니다. 나는 어느 쪽이 다른 쪽보다 빠르다는 주장을하지 않습니다. JSON이 더 빠르고 적절하다면 JSON으로 가십시오! (즉, 당신의 반대표에 대한 이유가 없습니다.)
— Håvard S

10
내 요점은 JSON을 통해 전제를 기반으로 cPickle(또는 pickle) 사용하는 실제 이유가 없다는 것 입니다. 내가 당신의 대답을 처음 읽었을 때 나는 그 이유가 속도 때문이라고 생각했지만 이것은 사실이 아니기 때문에 ... :)
— mac

14
@mac에서 인용 한 벤치 마크는 문자열 만 테스트합니다. str, int 및 float를 별도로 테스트 한 결과 json이 float 직렬화를 사용하는 cPickle보다 느리지 만 float 비 직렬화를 사용하면 더 빠릅니다. int (및 str)의 경우 json은 두 가지 모두 더 빠릅니다. 데이터 및 코드 : gist.github.com/marians/f1314446b8bf4d34e782
— 마리아

24
cPickle의 최신 프로토콜은 이제 JSON보다 빠릅니다. JSON이 더 빠르다는 찬성 의견은 몇 년 전에 구식입니다. stackoverflow.com/a/39607169/1007353
— JDiMatteo

104

직렬화를 위해 피클보다 JSON을 선호합니다. Unpickling은 임의의 코드를 실행할 수 pickle있으며 프로그램간에 데이터를 전송하거나 세션간에 데이터를 저장하는 데 사용하는 것은 보안 허점입니다. JSON은 보안 허점을 도입하지 않고 표준화되어 있으므로 필요한 경우 다른 언어로 된 프로그램에서 데이터에 액세스 할 수 있습니다.


감사. 어쨌든 나는 같은 프로그램에서 덤핑하고 로딩 할 것이다.
— Juanjo Conti

2
현재 애플리케이션에서는 보안 위험이 낮을 수 있지만 JSON을 사용하면 전체를 모두 닫을 수 있습니다.
— Mike Graham

4
로드 후 피클하는 모든 것에 피클하는 피클 바이러스를 만들 수 있습니다. json으로는 불가능합니다.
— User

2
보안 외에도 JSON은 마이그레이션을 쉽게한다는 추가적인 이점이 있으므로 이전 버전의 애플리케이션에서 저장 한 데이터를로드 할 수 있습니다. 한편 필드를 추가하거나 전체 하위 구조를 대체 할 수 있습니다. dict / list에 대한 이러한 변환기 (마이그레이션)를 작성하는 것은 간단하지만 Pickle을 사용하면 변환을 생각하기 전에 처음부터로드하기가 어려울 것입니다.
— vog

2
나는이 측면 (보안과 피클 된 객체가 임의의 코드를 실행하는 능력)에 대해 생각하지 않았습니다. 지적 해 주셔서 감사합니다!
— CaffeinatedMike

43

몇 가지 차트를 통해 흥미로운 사실을 발견 할 수도 있습니다. http://kovshenin.com/archives/pickle-vs-json-which-is-faster/


1
이 기사는 문자열과 관련된 성능 만 비교합니다. 다음은 별도로 테스트 문자열, 수레와의 int하기 위해 실행할 수있는 스크립트입니다 : gist.github.com/marians/f1314446b8bf4d34e782
— 마리아


20

주로 속도와 공간에 관심이 있다면 cPickle이 JSON보다 빠르기 때문에 cPickle을 사용하십시오.

상호 운용성, 보안 및 / 또는 사람의 가독성에 더 관심이 있다면 JSON을 사용하십시오.


다른 답변에서 참조 된 테스트 결과는 2010 년에 기록되었으며 2016 년 cPickle 프로토콜 2를 사용한 업데이트 된 테스트 는 다음을 보여줍니다.

  • cPickle 3.8 배 빠른 로딩
  • cPickle 1.5 배 더 빠른 읽기
  • c 약간 더 작은 인코딩 선택

다른 답변에서 참조 된 Konstantin의 벤치 마크를 기반으로 하지만 pickle 대신 프로토콜 2와 함께 cPickle을 사용하고 simplejson 대신 json을 사용 하는 이 요점으로 직접 재현하십시오 ( json이 simplejson보다 빠르기 때문에 ).

wget https://gist.github.com/jdimatteo/af317ef24ccf1b3fa91f4399902bb534/raw/03e8dbab11b5605bc572bc117c8ac34cfa959a70/pickle_vs_json.py
python pickle_vs_json.py

괜찮은 2015 Xeon 프로세서에서 Python 2.7을 사용한 결과 :

Dir Entries Method  Time    Length

dump    10  JSON    0.017   1484510
load    10  JSON    0.375   -
dump    10  Pickle  0.011   1428790
load    10  Pickle  0.098   -
dump    20  JSON    0.036   2969020
load    20  JSON    1.498   -
dump    20  Pickle  0.022   2857580
load    20  Pickle  0.394   -
dump    50  JSON    0.079   7422550
load    50  JSON    9.485   -
dump    50  Pickle  0.055   7143950
load    50  Pickle  2.518   -
dump    100 JSON    0.165   14845100
load    100 JSON    37.730  -
dump    100 Pickle  0.107   14287900
load    100 Pickle  9.907   -

피클 프로토콜 3을 사용하는 Python 3.4는 더 빠릅니다.


11

JSON 또는 피클? JSON 과 피클 은 어떻습니까 ! 사용할 수 있습니다 jsonpickle. 사용하기 쉽고 디스크의 파일은 JSON이기 때문에 읽을 수 있습니다.

http://jsonpickle.github.com/


2
옵션에 대한 성능을 벤치마킹 한 사람이 있습니까? 여기 benfrederickson.com/dont-pickle-your-data에서 볼 수 있듯이 성능면에서 원시 json과 비슷 합니까?
— Josep Valls

이것은 광범위한 벤치 마크는 아니지만 pickle (python3)을 사용하여 레벨을 저장하는 기존 게임이있었습니다. 인간이 읽을 수있는 측면을 위해 jsonpickle을 시도하고 싶었지만 레벨 저장은 슬프게도 훨씬 느 렸습니다. jsonpickle의 경우 1597ms, 레벨 저장시 88ms 또는 일반 피클. 레벨로드의 경우 jsonpickle의 경우 1604ms, pickle의 경우 388입니다. 인간이 읽을 수있는 저장을 좋아하는 유감입니다.
— Neil McGill

나는 이것을 우리의 거래 시스템에서 테스트했는데, 가독성은 피클에 비해 약 2 배의 직렬화 + 역 직렬화 속도 패널티와 함께 ​​제공됩니다. 그러나 다른 모든 것에 좋습니다.
— nurettin

6

몇 가지 방법을 시도한 결과 덤프 방법의 프로토콜 인수를 다음과 같이 설정하여 cPickle을 사용하는 cPickle.dumps(obj, protocol=cPickle.HIGHEST_PROTOCOL)것이 가장 빠른 덤프 방법 이라는 것을 알았습니다 .

import msgpack
import json
import pickle
import timeit
import cPickle
import numpy as np

num_tests = 10

obj = np.random.normal(0.5, 1, [240, 320, 3])

command = 'pickle.dumps(obj)'
setup = 'from __main__ import pickle, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("pickle:  %f seconds" % result)

command = 'cPickle.dumps(obj)'
setup = 'from __main__ import cPickle, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("cPickle:   %f seconds" % result)


command = 'cPickle.dumps(obj, protocol=cPickle.HIGHEST_PROTOCOL)'
setup = 'from __main__ import cPickle, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("cPickle highest:   %f seconds" % result)

command = 'json.dumps(obj.tolist())'
setup = 'from __main__ import json, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("json:   %f seconds" % result)


command = 'msgpack.packb(obj.tolist())'
setup = 'from __main__ import msgpack, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("msgpack:   %f seconds" % result)

산출:

pickle         :   0.847938 seconds
cPickle        :   0.810384 seconds
cPickle highest:   0.004283 seconds
json           :   1.769215 seconds
msgpack        :   0.270886 seconds

4

개인적으로 저는 데이터가 사람이 읽을 수 있기 때문에 일반적으로 JSON을 선호합니다 . 확실히, JSON이 취할 수없는 것을 직렬화해야한다면 pickle을 사용하십시오.

그러나 대부분의 데이터 저장소에서는 이상한 것을 직렬화 할 필요가 없으며 JSON은 훨씬 더 쉽고 항상 텍스트 편집기에서 열어 데이터를 직접 확인할 수 있습니다.

속도는 좋지만 대부분의 데이터 세트에서 그 차이는 미미합니다. 파이썬은 일반적으로 어쨌든 너무 빠르지 않습니다.



1
진실. 그러나 100목록에있는 요소의 경우 그 차이는 사람의 눈으로 완전히 무시할 수 있습니다. 더 큰 데이터 세트로 작업 할 때 확실히 다릅니다.
— rickcnagy 2014
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.