• 티스토리 홈
  • 프로필사진
    홀쑥
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
홀쑥
  • 프로필사진
    홀쑥
    • 분류 전체보기 (55)
      • Language (14)
        • Java (1)
        • Python (13)
      • DataBase (4)
        • NoSQL (1)
        • RDBMS (3)
      • OS (12)
        • Linux (10)
      • Etc (5)
        • 오류 모음 (5)
      • hadoop ecosystem (9)
        • Hadoop (4)
        • Hive (2)
        • Sqoop (1)
        • Zeppelin (1)
      • Cloud Service (0)
      • ELK STACK (2)
        • ElasticSearch (2)
      • Airflow (0)
      • Infra (0)
        • Docker (0)
        • Kubernetes (0)
      • Algorithm & Data Structure (7)
        • 백준 알고리즘 (6)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • [Python] JSON 직렬화와 역직렬화(json, ujson, orjson, msgspec)
        2025년 03월 22일
        • 홀쑥
        • 작성자
        • 2025.03.22.:34
        이번 게시글은 Python에서 JSON을 직렬화, 역직렬화 하는 패키지들을 비교해보려고 한다.
        TL;DR
        일반적인 사용 -> json
        속도와 성능 -> orjson
        MessagePack을 사용하거나 타입 검증이 필요 -> msgspec
        ujson -> 비추천(신규개발 중단)

        JSON이란?

        JSON(JavaScript Object Notation)은 Javascript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 표준 포맷이다.

        비록 Javascript 객체 문법이지만, 문자 기반이기에 다양한 플랫폼 및 프로그래밍 언어에서 사용할 수 있다.

        # JSON 예시
        {
        	"key1" : "value1",
            "key2" : "value2", 
            "key3" : {
            	"child_key_1" : "value3",
                "child_key_2" : "value4"
            },
            "key4" : [
            	...
            ],
        }

        직렬화와 역직렬화

        직렬화

        직렬화(Serialization)는 컴퓨터에서 데이터 구조나 객체 상태를 저장하거나 전송할 수 있는 형식으로 변환하고 후에 재구성이 가능하도록 하는 것이다. 보통 사람이 읽을 수 있는 문자를 사용한 텍스트 기반 형식과, 컴퓨터가 쉽게 읽을 수 있게 2진법(binary)으로 저장하는 형식이 있다. Marshalling이라고도 한다.

        역직렬화

        역직렬화(Deserialization)는 직렬화의 반대작업으로 직렬화된 텍스트 또는 2진법 형식을 데이터구조 또는 객체 상태로 재구성하는 과정이다. Unmarshalling이라고도 한다.

        Python에선?

        pickle

        • Python의 객체를 Byte 단위로 직렬화 하는 내장 모듈로 Python 전용 모듈이기에 다른 언어와 호환되지 않음

        json

        • Python의 딕셔너리, 리스트, 문자열, 숫자 등 기본 자료형들을 문자열로 직렬화하는 내장 모듈로 다른 언어와 호환됨

        Python에서 JSON 직렬화, 역직렬화

        • Python에선 JSON을 다루는 라이브러리들이 여러 개 존재한다(json, ujson, orjson, simplejson, rapidjson, ...)
        • 그 중 ujson, orjson, msgspec을 비교해보려고 한다.

        ujson(UltraJson)

        • UltraJSON은 C로 구현되어  빠른 속도를 가진 JSON 라이브러리이다.
        • 기본 내장모듈인 json보다 빠르고, json과 유사하게 사용할 수 있는 게 장점이다.
        • 하지만 Pypi 저장소에서 공식적으로 구조적으로 보안문제를 고치기 어려워 신규개발은 중단하고, 유지보수만 하겠다고 한다. 따라서 orjson으로 빠른 시일 내에 migrate하라고 한다.

        pypi 홈페이지의 내용 일부

        orjson(Optimized Rust Json)

        • optimized rust json은 Rust로 구현되어 매우 빠른 JSON 라이브러리로 Python 라이브러리 중 가장 빠르다.
        • 다른 종속성은 따로 없으며 CPython 3.8부터 지원되지만 PyPy, 모바일용 embedded Python build, PEP554 subinterpreters는 지원하지 않는다고 한다.
        • Python 생태계에서 인기를 얻고 있다고 한다.

        예제

        import orjson
        import datetime
        data = {'name': '햄', 'created': datetime.datetime.now()}
        serialized = orjson.dumps(data)
        # b'{"name":"thinmug","created":"2025-03-22T00:24:32.677298"}'
        serialized.decode('utf-8')
        # '{"name":"thinmug","created":"2025-03-22T00:24:32.677298"}'

         

        특징

        성능

        • 공식문서에 다른 서드파티 라이브러리보다 더 정확하고 빠르다고 설명하고 있으며 벤치마크 성능도 공개하고 있다.(ijl/orjson: Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy)
        • github의 README 서론에서 기존 json보다 직렬화는 약 10배, 역직렬화는 약 2배 빠르다고 한다.

        다양한 객체 직렬화 지원

        • 기존의 json은 위의 객체들은 직렬화가 안되어 다른과 같은 에러가 발생한다.
        # data에 datetime 객체가 들어있는 경우
        import datetime
        import json
        data = {'name': '햄', 'created': datetime.datetime.now()}
        serialized = json.dumps(data)
        """
        Traceback (most recent call last):
        ...
        TypeError: Object of type datetime is not JSON serializable
        """
        • 이렇게 직렬화가 지원되지 않는 객체에 대해선 JSONEncoder를 만들어 적용하거나 dumps 시엔 default 함수(변환함수)를 통하여 커스터마이징을 했었다.
        import json
        import datetime
        from dataclasses import dataclass
            
        def custom_default(obj):
        	"""datetime이나 기타 직렬화 불가능한 객체를 변환"""
            ...
        
            
        user = dict(name='thinmug', created=datetime.now())
        json_str = json.dumps(user, default=custom_default)
        
        class CustomEncoder(json.JSONEncoder):
        
            def default(self, obj):
            	"""default와 같음"""
        	...
            
        json_str = json.dumps(user, cls=CustomEncoder)
        • orjson을 사용할 경우 dataclass, datetime, numpy, 그리고 UUID 객체들도 직렬화를 지원한다.
        • default 파라미터를 통해 기존 json 라이브러리와 같이 사용할 수 있다.

        기본 반환값은 bytes 타입

        • 내장 json 라이브러리나 ujson과 달리 문자열이 아닌 utf-8로 인코딩된 bytes로 반환한다.
        • 디코딩이 필요할 경우엔 .decode('utf-8')을 통해 문자열로 치환이 필요하다.
        • 하지만 공식문서에 따르면 메모리 사용량과 속도를 위해선 디코딩없이 바로 넘기라고 한다.

        메모리 효율성

        • Rust 기반이기에 메모리관리가 효율적이기에, 대용량 데이터를 다룰 때 효율적이다.

        msgspec

        • orjson과 비교되는 C로 구현된 직렬화/역직렬화 라이브러리이다.
        • JSON뿐 만 아니라 MessagePack, Yaml, Toml 파일들을 지원한다.
        • 아직 생태계가 작은 것 같다.

        예제

        import msgspec
        import datetime
        
        class User(msgspec.Struct):
            name: str
            created: datetime.datetime
            
        data = User("thinmug", created=datetime.datetime.now())
        data
        # User(name='thinmug', created=datetime.datetime(2025, 3, 22, 1, 0, 35, 690114))
        
        serialized = msgspec.json.encode(data)
        serialized
        # b'{"name":"thinmug","created":"2025-03-22T01:00:35.690114"}'
        
        decode_user = msgspec.json.decode(serialized, type=User)
        decode_user
        # User(name='thinmug', created=datetime.datetime(2025, 3, 22, 1, 0, 35, 690114))
        
        decode_json = msgspec.json.decode(serialized)
        decode_json
        # {'name': 'thinmug', 'created': '2025-03-22T01:00:35.690114'}

        특징

        빠른성능

        • orjson과 비슷하거나 Struct 사용 시 더 높은 성능을 제공해준다.
        • 가벼운 라이브러리로 orjson과 마찬가지로 다른 종속성은 없다.
        • 공식문서에서 MessagePack과 JSON에서 가장 빠르다고 써있고 벤치마크도 공개되어 있는데 msgspec structs로 직렬화시 orjson보다 빠르다고 설명되어 있다.( Benchmarks)

        MessagePack 사용

        • MessagePack( MessagePack: It's like JSON. but fast and small.)은 바이너리 기반 직렬화로 JSON보다 더 빠르고, 작은 사이즈로 제공할 수 있으며 JSON과 같이 다양한 언어에서 사용할 수 있어 구글의 ProtoBuf와 함께 대중적으로 사용된다.

        JSON이 27bytes일 때 18bytes(2/3)만을 사용한다고 한다.

         

        다양한 객체 직렬화 제공

        • orjson과 비슷하거나 더 많은 객체 직렬화를 제공한다. (Supported Types)

        낮은 메모리 사용량

        • Struct가 내부적으로 최소한의 메모리로 압축하여 사용한다.
        • 객체 생성 및 처리 시 불필요한 메모리 할당 최소화한다고 한다.

        기본 반환값은 bytes 타입

        • orjson과 동일하게 직렬화 시 bytes 타입을 반환한다. 

        Struct 제공

        • msgspec은 고성능 데이터를 위해 Struct라는 타입(예제 참고)를 제공하는데, Python의 dataclass나 attrs와 유사하게 제공되어 친숙하게 사용할 수 있다.
        • Struct는 데이터의 구조화 및 직렬화, 역직렬화에 특화되어 dataclass 대비 5~60배 빠르다고 하며 Type Annotation을 통한 zero-cost 스키마 검증 기능을 제공한다.

        참고문서

        • MessagePack: It's like JSON. but fast and small.
        • msgspec · PyPI
        • https://github.com/ijl/orjson
        • JSON이란 무엇인가? | Oracle 대한민국
        • ujson · PyPI
        • https://en.wikipedia.org/wiki/Serialization
        • msgspec

         

         

         

         

         

        'Language > Python' 카테고리의 다른 글

        [Python] Polars의 데이터 타입과 구조  (0) 2025.04.10
        [Python] Polars, 빠른 속도와 낮은 메모리의 DataFrame 라이브러리  (1) 2025.04.04
        [Python] Python 3.11 cchardet fatal error: longintrepr.h: No such file or directory  (0) 2025.03.12
        Rocky Linux에 pyenv 설치  (0) 2024.12.02
        [Python] Poetry 사용법  (2) 2024.11.10
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바