ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • <PYTHON>[cPickle][msgpack][marshal]
    Flower in my dev/Python 2015. 9. 9. 09:37

    [cPickle][msgpack][marshal]


    -활용코드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    import cPickle
    import msgpack
    import marshal
     
    dic = {'a' : 'flower''b' : 'wing''c' : 'sky'}
     
    #===eval
    ts = str(dic)
    td = eval(ts)
    print "#===eval"
    print "str : %s" % ts
    for k,v in td.items():
        print "key : %s, value : %s" % (k, v)
     
    #===cPickle
    ts = cPickle.dumps(dic)
    td = cPickle.loads(ts)
    print "#===cPickle"
    print "str : %s" % ts
    for k,v in td.items():
        print "key : %s, value : %s" % (k, v)
     
    #===msgpack
    ts = msgpack.packb(dic)
    td = msgpack.unpackb(ts)
    print "#===msgpack"
    print "str : %s" % ts
    for k,v in td.items():
        print "key : %s, value : %s" % (k, v)
     
    #===marshal
    ts = marshal.dumps(dic)
    td = marshal.loads(ts)
    print "#===marshal"
    print "str : %s" % ts
    for k,v in td.items():
        print "key : %s, value : %s" % (k, v)
    cs


    -코드 결과




    -ipython 테스트






    - 지훈현서님 성능테스트 <출처 : http://egloos.zum.com/mcchae/v/11183324>


    d = { ... } # 사전 형 정의
    sd = str(d) # str로 dict 변환
    rd = eval(sd) # eval로 다시 dict 복원

    그리고 이런 역할로 Pickle과 cPickle이 있는데
    C 모듈로 되어 있어서 빠르다는 cPickle 로

    from cPickle import dumps, loads
    d = { ... } # 사전 형 정의
    sd = dumps(d) # dumps로 dict를 str로 변환
    rd = loads(sd) # loads로 다시 dict 복원

    그럼 이 둘 간의 속도 차이는 얼마나 날까요??
    (페북 친구분 께서 알려주신 python serialisation 의 내용처럼
     marshal과 msgpack 모듈을 이용하도록 추가해 보았습니다)

    #!/usr/bin/env python
    #coding=utf8

    ##########################################################################################
    from datetime import datetime
    import cPickle
    import marshal
    import msgpack

    ##########################################################################################
    def do_eval(obj, limit):
    sts = datetime.now()
    for i in xrange(limit):
    ds = str(obj)
    ls = eval(ds)
    if i == 0 and obj != ls: raise RuntimeError('obj revoke error!')
    ets = datetime.now()
    print('{} eval takes {}...'.format(limit, ets-sts))
    ##########################################################################################
    def do_pickle(obj, limit):
    sts = datetime.now()
    for i in xrange(limit):
    ds = cPickle.dumps(obj)
    ls = cPickle.loads(ds)
    if i == 0 and obj != ls: raise RuntimeError('obj revoke error!')
    ets = datetime.now()
    print('{} eval takes {}...'.format(limit, ets-sts))
    ##########################################################################################
    def do_msgpack(obj, limit):
    sts = datetime.now()
    for i in xrange(limit):
    ds = msgpack.packb(obj)
    ls = msgpack.unpackb(ds)
    if i == 0 and obj != ls: raise RuntimeError('obj revoke error!')
    ets = datetime.now()
    print('{} eval takes {}...'.format(limit, ets-sts))
    ##########################################################################################
    def do_marshal(obj, limit):
    sts = datetime.now()
    for i in xrange(limit):
    ds = marshal.dumps(obj)
    ls = marshal.loads(ds)
    if i == 0 and obj != ls: raise RuntimeError('obj revoke error!')
    ets = datetime.now()
    print('{} eval takes {}...'.format(limit, ets-sts))

    ##########################################################################################
    if __name__ == '__main__':
    limit = 100000
    obj = {'inpackets': 31125504, 'tunnel_error': 32, 'isregist': False,
    'port_line_normal': True, 'cpu_util': 82, 'outpackets': 33349120, 'type': 17,
    'isTunnelError': True, 'mem_util': 9, 'sessions': 5, 'activation': True,
    'inkbps': 80352, 'corp': 'NNACF', 'name': '\xec\x9e_00162',
    'center': 'internet', 'cid': 'f1c6c46e-8fc5-411f-b0b3-8f3061a58e1c',
    'net_util': 72, 'droppackets': 894, 'outkbps': 52596, 'time': 1441181768,
    'eth': [
    {'linkspeed': 0, 'inpackets': 0, 'ip': 0, 'util': 0, 'bandwidth': 0,
    'num': 0, 'type': 'normal', 'ipsec': False, 'outbytes': 0,
    'isLinkDown': True, 'inbytes': 0, 'dropbytes': 0, 'droppackets': 0, 'kbps': 0},
    {'linkspeed': 3703, 'inpackets': 257630, 'ip': 4578, 'util': 75,
    'bandwidth': 78828262, 'num': 730, 'type': 'normal', 'ipsec': False,
    'outbytes': 5545400, 'isLinkDown': False, 'inbytes': 4139600,
    'dropbytes': 703, 'droppackets': 4, 'kbps': 891},
    {'linkspeed': 8571, 'inpackets': 143510, 'ip': 3835, 'util': 32,
    'bandwidth': 90670011, 'num': 653, 'type': 'normal', 'ipsec': False,
    'outbytes': 6588100, 'isLinkDown': False, 'inbytes': 1232100,
    'dropbytes': 648, 'droppackets': 8, 'kbps': 4213},
    {'linkspeed': 0, 'inpackets': 0, 'ip': 0, 'util': 0, 'bandwidth': 0,
    'num': 0, 'type': 'normal', 'ipsec': False, 'outbytes': 0,
    'isLinkDown': True, 'inbytes': 0, 'dropbytes': 0, 'droppackets': 0,
    'kbps': 0},
    {'linkspeed': 29801, 'inpackets': 588020, 'ip': 1952, 'util': 30,
    'bandwidth': 83466247, 'num': 581, 'type': 'normal', 'ipsec': False,
    'outbytes': 9945500, 'isLinkDown': False, 'inbytes': 3435800,
    'dropbytes': 647, 'droppackets': 6, 'kbps': 1092},
    {'linkspeed': 0, 'inpackets': 0, 'ip': 0, 'util': 0, 'bandwidth': 0,
    'num': 0, 'type': 'normal', 'ipsec': False, 'outbytes': 0,
    'isLinkDown': True, 'inbytes': 0, 'dropbytes': 0, 'droppackets': 0,
    'kbps': 0},
    {'linkspeed': 14359, 'inpackets': 557100, 'ip': 2921, 'util': 32,
    'bandwidth': 18209429, 'num': 40, 'type': 'normal', 'ipsec': False,
    'outbytes': 1155200, 'isLinkDown': False, 'inbytes': 8787100,
    'dropbytes': 906, 'droppackets': 2, 'kbps': 5829},
    {'linkspeed': 6704, 'inpackets': 913340, 'ip': 2405, 'util': 73,
    'bandwidth': 884716, 'num': 86, 'type': 'normal', 'ipsec': False,
    'outbytes': 3145900, 'isLinkDown': False, 'inbytes': 5141200,
    'dropbytes': 493, 'droppackets': 0, 'kbps': 11661}], 'dropkbps': 1}
    do_eval(obj, limit)
    do_pickle(obj, limit)
    do_msgpack(obj, limit)
    do_marshal(obj, limit)

    위와 같은 코드를 돌려 보았습니다.
    (timeit 등으로 하지 않아도 뭐 결과는 거의 똑 같았습니다.)

    marshal 은 기본 모듈이었기 때문에 그냥 돌리면 되구요,
    msgpack은

    $ sudo pip install msgpack-python
    라고 설치하시면 됩니다.

    $ python dict_str.py 
    100000 eval takes 0:00:30.173971...
    100000 eval takes 0:00:07.915188...
    100000 eval takes 0:00:02.108029...
    100000 eval takes 0:00:01.497583...


    결과에 의하면 cPickle 을 사용하는 경우가 eval을 사용하는 경우보다
    거의 4배 정도 더 빠름을 알 수 있었습니다.

    헉! marshal 기본 모듈을 이용하면 다시 5배 이상 줄어드는 군요.
    원래 eval에 비해서는 20배 이상 차이가 났습니다.

    초당 10000개 정도의 무언가를 한다고 할 때,
    eval을 사용하면 결코 할 수 없는 상황이 되겠군요...


    어느 분께는 도움이 되셨기를...


    - 지훈현서님 언제나 도움이 되고있습니다. 감사합니다.

    'Flower in my dev > Python' 카테고리의 다른 글

    <PYTHON>[pygoogle]  (0) 2015.09.09
    <PYTHON>[pygeoip]  (0) 2015.09.09
    <PYTHON>[paramiko sftp]  (0) 2015.09.03
    <PYTHON>[json]  (0) 2015.08.21
    <PYTHON>[platform]  (0) 2015.08.21

    댓글

Designed by Tistory.