[php] PHP 배열을 저장하는 데 선호되는 방법 (json_encode와 serialize)

캐싱을 위해 다차원 연관 데이터 배열을 플랫 파일에 저장해야합니다. 웹 응용 프로그램에서 사용하기 위해 JSON으로 변환 해야하는 경우가 종종 있지만 대부분의 경우 PHP에서 직접 배열을 사용합니다.

이 텍스트 파일에서 배열을 JSON 또는 PHP 직렬 배열로 저장하는 것이 더 효율적입니까? 나는 주변을 둘러 보았고 최신 버전의 PHP (5.3)에서는 json_decode실제로보다 빠릅니다 unserialize.

필자는 필요한 경우 사람이 쉽게 읽을 수 있다고 생각하여 배열을 JSON으로 저장하는 데 기울이고 있습니다. PHP와 JavaScript 모두에 거의 노력을 기울이지 않고 읽을 수 있습니다. 디코딩 속도가 빠릅니다 (그러나 인코딩에 대해서는 확실하지 않습니다).

함정에 대해 아는 사람이 있습니까? 누구든지 두 가지 방법의 성능 이점을 보여줄 좋은 벤치 마크가 있습니까?



답변

우선 순위에 따라 다릅니다.

성능이 절대 주행 특성이라면 반드시 가장 빠른 주행 특성을 사용하십시오. 선택하기 전에 차이점을 완전히 이해하고 있는지 확인하십시오.

  • 달리 serialize()당신의 손길이 닿지 않은 UTF-8 문자를 유지하기 위해 추가 매개 변수를 추가해야합니다 json_encode($array, JSON_UNESCAPED_UNICODE) (그렇지 않으면 유니 코드 이스케이프 시퀀스에 UTF-8 문자로 변환).
  • JSON에는 객체의 원래 클래스에 대한 메모리가 없습니다 (항상 stdClass의 인스턴스로 복원됩니다).
  • 당신은 활용할 수 없습니다 __sleep()__wakeup()JSON과
  • 기본적으로 공개 특성 만 JSON으로 직렬화됩니다. ( 이 동작을 변경하기 위해 JsonSerializablePHP>=5.4구현할 수 있습니다 ).
  • JSON은 더 이식성이 뛰어납니다

그리고 지금은 생각할 수없는 몇 가지 차이점이있을 것입니다.

두 가지를 비교하는 간단한 속도 테스트

<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

// Make a big, honkin test array
// You may need to adjust this depth to avoid memory limit errors
$testArray = fillArray(0, 5);

// Time json encoding
$start = microtime(true);
json_encode($testArray);
$jsonTime = microtime(true) - $start;
echo "JSON encoded in $jsonTime seconds\n";

// Time serialization
$start = microtime(true);
serialize($testArray);
$serializeTime = microtime(true) - $start;
echo "PHP serialized in $serializeTime seconds\n";

// Compare them
if ($jsonTime < $serializeTime) {
    printf("json_encode() was roughly %01.2f%% faster than serialize()\n", ($serializeTime / $jsonTime - 1) * 100);
}
else if ($serializeTime < $jsonTime ) {
    printf("serialize() was roughly %01.2f%% faster than json_encode()\n", ($jsonTime / $serializeTime - 1) * 100);
} else {
    echo "Impossible!\n";
}

function fillArray( $depth, $max ) {
    static $seed;
    if (is_null($seed)) {
        $seed = array('a', 2, 'c', 4, 'e', 6, 'g', 8, 'i', 10);
    }
    if ($depth < $max) {
        $node = array();
        foreach ($seed as $key) {
            $node[$key] = fillArray($depth + 1, $max);
        }
        return $node;
    }
    return 'empty';
}


답변

JSON 은 PHP의 직렬화 형식보다 간단하고 빠르며 다음과 같은 경우를 제외 하고 사용해야합니다 .

  • 깊이 중첩 된 배열을 저장하고 있습니다.
    json_decode(): “JSON 인코딩 데이터가 127 개 요소보다 깊은 경우이 함수는 false를 반환합니다.”
  • 올바른 클래스로 직렬화 해제 해야하는 객체를 저장하고 있습니다.
  • json_decode를 지원하지 않는 이전 PHP 버전과 상호 작용하고 있습니다.

답변

이 주제에 대한 블로그 포스트를 작성했습니다 : 큰 배열을 캐시하십시오 : JSON, serialize 또는 var_export? . 이 게시물에서는 직렬화가 중소형 어레이에 가장 적합한 선택임을 보여줍니다. 매우 큰 배열 (> 70MB)의 경우 JSON이 더 좋습니다.


답변

PHP에 다른 직렬화 ‘엔진’을 제공하는 https://github.com/phadej/igbinary에 관심이있을 수도 있습니다 .

64 비트 플랫폼 쇼에서 PHP 5.3.5를 사용하는 임의 / 임의의 ‘성능’수치 :

JSON :

  • 2.180496931076 초로 인코딩 된 JSON
  • 9.8368630409241 초 안에 JSON 디코딩
  • 직렬화 된 “문자열”크기 : 13993

네이티브 PHP :

  • PHP는 2.9125759601593 초에 직렬화되었습니다.
  • 6.4348418712616 초 내에 PHP 직렬화 해제
  • 직렬화 된 “문자열”크기 : 20769

이그 너리 :

  • WIN 이진이 1.6099879741669 초에 직렬화 됨
  • 4.7737920284271 초 후에 직렬화되지 않은 WIN 이진
  • WIN 직렬화 “문자열”크기 : 4467

따라서 igbinary_serialize () 및 igbinary_unserialize ()가 더 빠르며 디스크 공간을 적게 사용합니다.

위와 같이 fillArray (0, 3) 코드를 사용했지만 배열 키를 더 긴 문자열로 만들었습니다.

igbinary는 PHP의 native serialize can과 동일한 데이터 타입을 저장할 수 있으며 (따라서 객체에 아무런 문제가 없음) PHP5.3에게 원한다면 세션 처리에 사용하도록 지시 할 수 있습니다.

http://ilia.ws/files/zendcon_2010_hidden_features.pdf 참조 -특히 슬라이드 14/15/16


답변

Y는 직렬화 및 json 인코딩 및 디코딩 테스트와 저장된 문자열의 크기를 테스트했습니다.

JSON encoded in 0.067085981369 seconds. Size (1277772)
PHP serialized in 0.12110209465 seconds. Size (1955548)
JSON decode in 0.22470498085 seconds
PHP serialized in 0.211947917938 seconds
json_encode() was roughly 80.52% faster than serialize()
unserialize() was roughly 6.02% faster than json_decode()
JSON string was roughly 53.04% smaller than Serialized string

JSON 인코딩 속도가 더 빠르고 문자열이 더 작지만 직렬화가 빠르면 문자열을 디코딩하는 것이 빠르다는 결론을 내릴 수 있습니다.


답변

나중에 “포함”할 정보를 캐싱하는 경우 var_export 를 사용해보십시오 . 그렇게하면 “직렬화”가 아닌 “직렬화”에서만 적중합니다.


답변

직렬화 해제 성능을 포함하도록 테스트를 보강했습니다. 내가 얻은 숫자는 다음과 같습니다.

Serialize

JSON encoded in 2.5738489627838 seconds
PHP serialized in 5.2861361503601 seconds
Serialize: json_encode() was roughly 105.38% faster than serialize()


Unserialize

JSON decode in 10.915472984314 seconds
PHP unserialized in 7.6223039627075 seconds
Unserialize: unserialize() was roughly 43.20% faster than json_decode() 

따라서 json은 인코딩 속도는 빠르지 만 디코딩 속도는 느립니다. 따라서 응용 프로그램과 가장 기대하는 작업에 따라 달라질 수 있습니다.