programing

피클이야, 존이야?

megabox 2023. 3. 15. 19:29
반응형

피클이야, 존이야?

디스크에 저장해야 합니다.dict키가 타입인 오브젝트str및 값은int복구합니다.다음과 같은 경우:

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

가장 좋은 선택지와 그 이유는 무엇입니까?연재하다pickle또는 을 사용하여simplejson?

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

나는 JSON을 피클보다 더 좋아한다.스크리킹을 해제하면 임의의 코드를 실행할 수 있으며pickle프로그램 간에 데이터를 전송하거나 세션 간에 데이터를 저장하는 것은 보안상의 구멍입니다.JSON은 보안 취약점을 도입하지 않고 표준화되어 있기 때문에 필요에 따라 다른 언어로 된 프로그램을 통해 데이터에 액세스할 수 있습니다.

상호운용성 요건이 없고(예를 들어 Python에서 데이터를 사용하는 경우) 바이너리 포맷이 괜찮다면 Python 오브젝트 시리얼라이제이션이 매우 빠른 cPickle을 선택하십시오.

상호 운용성을 원하거나 데이터를 저장할 텍스트 형식을 원하는 경우 JSON(또는 제약 조건에 따라 다른 적절한 형식)을 선택합니다.

비교 대상이 되는 차트도 있습니다.http://kovshenin.com/archives/pickle-vs-json-which-is-faster/

속도와 공간을 주로 고려하는 경우 cPickle이 JSON보다 빠르기 때문에 cPickle을 사용하십시오.

상호운용성, 보안 및/또는 사람의 가독성에 관심이 있는 경우 JSON을 사용합니다.


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

  • cPickle 3.8배 고속 로딩
  • cPickle 1.5배 빠른 읽기 속도
  • cPickle 부호화가 약간 작다

다른 답변에서 언급된 Constantin의 벤치마크를 기반으로 한 요지를 사용하여 직접 재현합니다. 단, 피클 대신 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   -

Python 3.4와 피클 프로토콜 3은 훨씬 더 빠릅니다.

JSON 아니면 피클?JSON이랑 피클 어때?

사용할 수 있습니다.jsonpickleJSON이기 때문에 사용하기 쉽고 디스크상의 파일을 읽을 수 있습니다.

jsonpickle 매뉴얼 참조

몇 가지 방법을 시도해보니 덤프 방식의 protocol 인수를 다음과 같이 설정하고 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

개인적으로 JSON은 사람이 읽을 수 있는 데이터이기 때문에 선호합니다.물론 JSON이 받아들이지 않는 것을 연재할 필요가 있다면 피클을 사용하는 것이 좋습니다.

그러나 대부분의 데이터 스토리지에서는 이상한 것을 시리얼화할 필요가 없으며 JSON이 훨씬 쉬워 항상 텍스트 에디터로 팝업하여 데이터를 직접 확인할 수 있습니다.

속도는 좋지만 대부분의 데이터셋의 경우 차이가 거의 없습니다. Python은 일반적으로 그리 빠르지 않습니다.

대부분의 답변은 오래되어 정보가 누락되어 있습니다.

"Unpickling은 임의 코드를 실행할 수 있습니다" 문장의 경우:
  1. https://docs.python.org/3/library/pickle.html#restricting-globals 의 예를 확인해 주세요.
import pickle
pickle.loads(b"cos\nsystem\n(S'echo hello world'\ntR.")
pickle.loads(b"cos\nsystem\n(S'pwd'\ntR.")

pwd can can가((((((((((((((예:rm파일을 삭제합니다.

  1. 자세한 내용은 https://checkoway.net/musings/pickle/에서 "임의 코드 실행" 템플릿을 확인하십시오.코드는 python2.7로 작성되어 있습니다만, 조금 수정하면 python3에서도 동작할 수 있을 것 같습니다.만약 python3에서 작동한다면 python3 version my answer를 추가해주세요.:)
"피클 속도 vs json" 파트의 경우:

우선 python3에는 현재 명시적인 내용이 없습니다.

이 한 것입니다.picklejson★★★★

import pickle
import json, random
from time import time
from hashlib import md5

test_runs = 100000

if __name__ == "__main__":
    payload = {
        "float": [(random.randrange(0, 99) + random.random()) for i in range(1000)],
        "int": [random.randrange(0, 9999) for i in range(1000)],
        "str": [md5(str(random.random()).encode('utf8')).hexdigest() for i in range(1000)]
    }
    modules = [json, pickle]

    for payload_type in payload:
        data = payload[payload_type]
        for module in modules:
            start = time()
            if module.__name__ in ['pickle']:
                for i in range(test_runs): serialized = module.dumps(data)
            else:
                for i in range(test_runs): 
                    # print(i)
                    serialized = module.dumps(data)
            w = time() - start
            start = time()
            for i in range(test_runs):
                unserialized = module.loads(serialized)
            r = time() - start
            print("%s %s W %.3f R %.3f" % (module.__name__, payload_type, w, r))

결과:

tian@tian-B250M-Wind:~/playground/pickle_vs_json$ p3 pickle_test.py 
json float W 41.775 R 26.738
pickle float W 1.272 R 2.286
json int W 5.142 R 4.974
pickle int W 0.589 R 1.352
json str W 10.379 R 4.626
pickle str W 3.062 R 3.294

언급URL : https://stackoverflow.com/questions/2259270/pickle-or-json

반응형