Быстрее JSON - orjson | Тема месяца Python

задняя часть Python

Эта статья участвует в "Месяце тем Python", подробнее см.Ссылка на мероприятие

Поиск общедоступных номеров WeChat [Программа Юань Сяочжуан], Ленивый человек не может наслаждаться отдыхом~

предисловие

JSON, использующий больше, тем больше вероятность столкнуться с проблемой кодирования или декодирования JSON, встроенная библиотека Python Python, хотя и очень проста в использовании, но есть много других более быстрых библиотек JSON, которые можно использовать, но конкретный выбор того, какой из них или который должен быть конкретным обстоятельствах, не существует стандартного правила или наилучшего показателя, который JSON быстрее всего, потому что разные проекты имеют разные потребности, и некоторые из них сосредоточены на безопасности, а некоторые на более быстром, этот документбыстрее json-orjson.

Введение в орджсон

orjsonэто более быстрая библиотека Python JSON, найденная тестами, чем стандартная библиотека json иrapidjsonБолее высокая скорость, может быть сериализованdataclass datetime numpy UUID,json或者rapidjsonпо сравнению сorjsonРезультат сериализацииbytesвведите вместоjson格式的str类型, сериализация не будетunicodeпреобразовать вASCII, должны знать о том,orjsonНе предоставленdump/loadметод реализацииfile-likeОбъекты сериализуются и десериализуются. больше оorjsonпожалуйста, используйтеОбратитесь к официальной документации.

Сравнение скорости jsonrapson и orjson

Нижеjson rapidjson orjsonВыполненный контрольный код и результаты.

import json
import orjson
import rapidjson
import time

m = {
    "timestamp": 1556283673.1523004,
    "task_uuid": "0ed1a1c3-050c-4fb9-9426-a7e72d0acfc7",
    "task_level": [1, 2, 1],
    "action_status": "started",
    "action_type": "main",
    "key": "value",
    "another_key": 123,
    "and_another": ["a", "b"],
}


def benchmark(module_name, dumps):
    start = time.time()
    for i in range(100000):
        dumps(m)
    print(module_name, time.time() - start)


benchmark('json', json.dumps)
benchmark('rapidjson', rapidjson.dumps)
benchmark("orjson", lambda s: str(orjson.dumps(s), "utf-8"))  # orjson只能输出bytes

и результат следующий,orjsonДаже если требуется дополнительное декодирование Unicode, оно является самым быстрым, но это не значит, что блогер должен рекомендовать его вам.orjson, вам нужно выбрать в соответствии с реальной ситуацией ~:

json 1.1019978523254395
rapidjson 0.25800156593322754
orjson 0.0859987735748291

Основное использование orjson

orjsonУстановить

Команда установки очень проста:pip install orjson

Следует отметить, что в среде Linux с использованиемpipкоманда при установкеpipВерсия должна быть выше 19.3, поэтому после установкиorjsonМожет быть обновлено первымpipВерсия.

orjsonосновное использование

Сериализация

и стандартная библиотека Python JSONjsonСамая большая разница в том, чтоorjson.dumpsВозвращаемый результатbytesиjson.dumpsВозвращаемый результатstr.sort_keysПараметрoption=orjson.OPT_SORT_KEYSзаменять,indentпараметрoption=orjson.OPT_INDENT_2заменяет и не поддерживает другиеindentоценка.

def dumps(
    __obj: Any,
    default: Optional[Callable[[Any], Any]] = ...,
    option: Optional[int] = ...,
) -> bytes: ...
    
# 序列化
import orjson

m = {
    "timestamp": 1556283673.1523004,
    "task_uuid": "0ed1a1c3-050c-4fb9-9426-a7e72d0acfc7",
    "task_level": [1, 2, 1],
    "action_status": "started",
    "action_type": "哈哈",
    "key": "value",
    "another_key": 123,
    "and_another": ["a", "b"],
}


res = orjson.dumps(m)
print(res)  
# b'{"timestamp":1556283673.1523004,"task_uuid":"0ed1a1c3-050c-4fb9-9426-a7e72d0acfc7","task_level":[1,2,1],"action_status":"started","action_type":"\xe5\x93\x88\xe5\x93\x88","key":"value","another_key":123,"and_another":["a","b"]}'

десериализовать-нагрузки

loadsМетоды байтов данных в формате JSON десериализуют объекты, на которые ссылается образец Python.

print(orjson.loads(res))

float int strТип сериализация и десериализация

float

orjsonНет потери точности при сериализации и десериализации номеров с плавающей точкой двойной точности, вjson rapidjsonПотери в точности тоже нет.orjson.dumpsСериализацияNan,Infinity,-Infinityнесовместимо, получитсяnullрезультат, ноjson和rapidjsonслужба поддержки.

>>> import orjson, ujson, rapidjson, json
>>> orjson.dumps([float("NaN"), float("Infinity"), float("-Infinity")])
b'[null,null,null]'
>>> rapidjson.dumps([float("NaN"), float("Infinity"), float("-Infinity")])
'[NaN,Infinity,-Infinity]'
>>> json.dumps([float("NaN"), float("Infinity"), float("-Infinity")])
'[NaN, Infinity, -Infinity]'

int

orjsonПо умолчанию 64-разрядные сертификаты можно сериализовать и десериализовать. Поддерживаемый диапазон — от минимального значения со знаком (-9223372036854775807) до максимального значения без знака (18446744073709551615), но в некоторых сценариях поддерживаются только 53-разрядные сертификаты. браузеры, для несовместимых частей,dumpsметод выдастJSONEncodeErrorаномальный.

>>> import orjson
>>> orjson.dumps(9007199254740992)
b'9007199254740992'
>>> orjson.dumps(9007199254740992, option=orjson.OPT_STRICT_INTEGER)
JSONEncodeError: Integer exceeds 53-bit range
>>> orjson.dumps(-9007199254740992, option=orjson.OPT_STRICT_INTEGER)
JSONEncodeError: Integer exceeds 53-bit range

str

orjsonСтрогое соответствие UTF8, лучше, чем стандартная библиотека Python.jsonболее строгий,jsonИспользуйте UTF-16 для прокси при сериализации и десериализации, но UTF8 недоступен. еслиorjson.dumpsЕсли параметр передает символ, отличный от UTF8, он выдаетorjson.JSONEncodeErrorисключение, еслиorjson.loads()Такое же исключение брошено, когда параметр получает недоступный символ UTF8.

orjson和rapidjsonИ стандартная библиотека PythonjsonНапротив, соответствующее исключение всегда генерируется для ввода, который не соответствует правилам.

Для надежности программы ее можно сначала десериализовать.bytesТип кодируется в формате UTF8.

>>> import orjson
>>> orjson.loads(b'"\xed\xa0\x80"')
JSONDecodeError: str is not valid UTF-8: surrogates not allowed
>>> orjson.loads(b'"\xed\xa0\x80"'.decode("utf-8", "replace"))

Эпилог

Статья была впервые опубликована в публичном аккаунте WeChat.Программа маленькой деревни Юань, синхронизировано сНаггетс.

Кодировать слова непросто, объясните, пожалуйста, источник перепечатки, а маленькие друзья, которые проходят мимо, протягивают свои милые пальчики и ставят лайк перед уходом (╹▽╹)

image.png