PHP 어레이를 저장하는 데 선호되는 방법(json_encode vs serialize)
캐싱을 위해 데이터의 다차원 연관 배열을 플랫 파일에 저장해야 합니다.가끔 웹 앱에서 사용하기 위해 JSON으로 변환해야 하는 경우가 있지만 대부분의 경우 PHP에서 직접 어레이를 사용하게 됩니다.
이 텍스트 파일에 어레이를 JSON으로 저장하는 것이 더 효율적일까요, 아니면 PHP 직렬 어레이로 저장하는 것이 더 효율적일까요?(5는 PHP(5.3)로 있는 것 .json_decode
~ ~unserialize
.
저는 현재 어레이를 JSON으로 저장하는 것을 고려하고 있습니다.필요하면 PHP와 JavaScript 모두에서 매우 쉽게 사용할 수 있고, 제가 읽은 바로는 디코딩하는 것이 더 빠를 수도 있기 때문입니다(다만 인코딩에 대해서는 확실하지 않습니다).
함정에 대해 아는 사람 있나요?두 방법의 성능 이점을 보여주는 좋은 벤치마크를 가진 사람이 있습니까?
우선순위에 따라 다르죠
성능이 운전의 절대적인 특징이라면 반드시 가장 빠른 것을 사용하십시오.선택하기 전에 차이점을 완전히 이해해야 합니다.
- ★★★★★★★★★★★★★★★와 달리
serialize()
변경하지 유지하려면 해야 합니다.UTF-8 문자는 UTF-8 문자입니다.json_encode($array, JSON_UNESCAPED_UNICODE)
(그 이외의 경우는, UTF-8 문자를 Unicode 이스케이프 시퀀스로 변환합니다). - JSON에는 객체의 원래 클래스가 무엇인지에 대한 메모리가 없습니다(항상 stdClass 인스턴스로 복원됩니다).
- 할 수
__sleep()
★★★★★★★★★★★★★★★★★」__wakeup()
JSONJSON with함 with with - JSON에서는).
PHP>=5.4
JsonSerialable을 구현하여 이 동작을 변경할 수 있습니다). - 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 인코딩된 데이터가 127개 요소보다 깊으면 이 함수는 false를 반환합니다."
- 직렬화 해제해야 하는 개체를 올바른 클래스로 저장하고 있습니다.
- json_decode를 지원하지 않는 이전 PHP 버전과 상호 작용하고 있습니다.
이 주제에 관한 블로그 투고: "대형 어레이 캐시: JSON, serialize or var_export?"이 투고에서는, 시리얼라이즈가 중소규모 어레이에 최적인 것을 나타내고 있습니다.매우 큰 어레이(70MB 이상)의 경우 JSON을 선택하는 것이 좋습니다.
PHP용 다른 직렬화 '엔진'을 제공하는 https://github.com/phadej/igbinary에도 관심이 있을 수 있습니다.
64비트 플랫폼에서 PHP 5.3.5를 사용한 랜덤/임의의 '퍼포먼스' 수치는 다음과 같습니다.
JSON:
- JSON은 2.180496931076초로 부호화
- JSON은 9.8368630409241초만에 디코딩되었습니다.
- 시리얼화된 "String" 크기: 13993
네이티브 PHP:
- PHP가 2.9125759601593초만에 시리얼화됨
- PHP가 6.4348418712616초만에 시리얼 해제됨
- 시리얼화된 "String" 크기: 20769
Igbinary:
- 1.609987741669초만에 시리얼화된 WIN igbinary
- WIN igbinary unserialize (4.7737920284271초)
- WIN 시리얼화 "String" 사이즈 : 4467
따라서 igbinary_serialize() 및 igbinary_unserialize()가 더 빠르고 디스크 공간을 덜 사용합니다.
위와 같이 fillArray(0, 3) 코드를 사용했는데, 배열 키를 긴 문자열로 만들었습니다.
igbinary는 PHP의 네이티브 serialize와 같은 데이터 타입을 저장할 수 있습니다(오브젝트 등의 문제는 없습니다).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은 인코딩은 빠르지만 디코딩은 느린 것 같습니다.따라서 애플리케이션 및 가장 기대되는 작업에 따라 달라질 수 있습니다.
정말 좋은 주제이고, 몇 가지 답을 읽은 후에, 나는 그 주제에 대한 나의 실험들을 공유하고 싶다.
데이터베이스와 대화할 때마다 일부 "대규모" 테이블을 쿼리해야 하는 사용 사례가 있습니다(이유는 묻지 말고 사실만 확인).데이터베이스 캐싱 시스템은 서로 다른 요청을 캐싱하지 않기 때문에 적절하지 않기 때문에 php 캐싱 시스템에 대해 생각했습니다.
는 는 i i는노노 i i i i i.apcu
이 경우 메모리 신뢰성이 떨어지기 때문에 요구에 맞지 않습니다.다음 단계는 시리얼라이제이션으로 파일에 캐시하는 것이었습니다.
테이블에는 14355개의 엔트리가 있으며 18개의 컬럼이 있습니다.이것이 시리얼라이즈된 캐시를 읽기 위한 테스트와 통계입니다.
JSON:
하셨듯이, ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★json_encode
/json_decode
을 「모든 것」으로 합니다.StdClass
instance('인스턴스')로 변환하는 것이 .그렇습니다.변환 시간이 길어집니다.
평균 시간: 780.2 ms, 메모리 사용량: 41.5MB, 캐시 파일 크기: 3.8MB
메시지 팩
@msgch는 msgpack을 언급하고 있습니다.웹사이트가 예쁘네요.한번 해볼까?
평균 시간: 497 ms, 메모리 사용량: 32 MB, 캐시 파일 크기: 2.8MB
그게 낫긴 한데, 새로운 확장이 필요해. 가끔은 겁에 질린 사람들을 모아서...
이그바이너리
@Ginger Dog은 igbinary를 언급하고 있다.주의해 주세요.igbinary.compact_strings=Off
왜냐하면 저는 파일 크기보다 읽기 성능에 더 신경을 쓰기 때문입니다.
평균 시간: 411.4 ms, 메모리 사용량: 36.75 MB, 캐시 파일 크기: 3.3MB
msg 팩보다 낫습니다.하지만 이것도 컴파일이 필요합니다.
serialize
/unserialize
평균 시간: 477.2 ms, 메모리 사용: 36.25 MB, 캐시 파일 크기: 5.9MB
JSON 속도가 .json_decode
하지만 넌 이미 그걸 알고 있잖아
이러한 외부 확장자로 인해 파일 크기가 좁아지고 있어 서류상으로는 훌륭해 보입니다.숫자는 거짓말이 아닙니다.*표준 PHP 함수와 거의 동일한 결과를 얻을 수 있다면 확장자를 컴파일하는 것이 무슨 의미가 있습니까?
또, 고객의 요구에 따라, 다른 유저와는 다른 것을 선택할 수도 있습니다.
- IgBinary는 MsgPack보다 성능이 우수합니다.
- 데이터 압축은 Msgpack이 더 잘합니다(igbinary compact.string 옵션은 시도하지 않았습니다).
- 컴파일하지 않으시겠습니까?표준을 사용합니다.
이상, 다른 시리얼라이제이션 방법을 비교해 보겠습니다.
*PHPUnit 3.7.31, ph 5.5.10에서 테스트 - 표준 하드 드라이브와 이전 듀얼 코어 CPU에서만 디코딩 - 10개의 동일한 사용 사례 테스트에서 평균 수치는 다를 수 있습니다.
다음 두 가지 이유로 serialize를 사용하는 것 같습니다.
어떤 사람은 직렬화를 해제하는 것이 json_decode보다 빠르고, '읽기' 대소문자가 '쓰기' 대소문자보다 더 가능성이 높다고 지적했습니다.
UTF-8 문자가 유효하지 않은 문자열이 있을 때 json_encode에 문제가 있었습니다.이 경우 문자열이 비게 되어 정보가 손실됩니다.
모든 종류의 데이터(문자열, NULL, 정수)가 포함된 상당히 복잡하고 약간 중첩된 멀티 해시에 대해 이 문제를 철저히 테스트했습니다. serialize/unserialize는 json_encode/json_decode보다 훨씬 더 빨리 종료되었습니다.
내 테스트에서 json이 가진 유일한 장점은 작은 포장 크기였다.
이것들은 PHP 5.3.3에서 행해지고 있습니다.자세한 내용이 필요하시면 알려주세요.
다음은 테스트 결과 및 테스트 결과를 생성하는 코드입니다.야생에서 내보낼 수 없는 정보가 노출되기 때문에 테스트 데이터를 제공할 수 없습니다.
JSON encoded in 2.23700618744 seconds
PHP serialized in 1.3434419632 seconds
JSON decoded in 4.0405561924 seconds
PHP unserialized in 1.39393305779 seconds
serialized size : 14549
json_encode size : 11520
serialize() was roughly 66.51% faster than json_encode()
unserialize() was roughly 189.87% faster than json_decode()
json_encode() string was roughly 26.29% smaller than serialize()
// Time json encoding
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
json_encode( $test );
}
$jsonTime = microtime( true ) - $start;
echo "JSON encoded in $jsonTime seconds<br>";
// Time serialization
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
serialize( $test );
}
$serializeTime = microtime( true ) - $start;
echo "PHP serialized in $serializeTime seconds<br>";
// Time json decoding
$test2 = json_encode( $test );
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
json_decode( $test2 );
}
$jsonDecodeTime = microtime( true ) - $start;
echo "JSON decoded in $jsonDecodeTime seconds<br>";
// Time deserialization
$test2 = serialize( $test );
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
unserialize( $test2 );
}
$unserializeTime = microtime( true ) - $start;
echo "PHP unserialized in $unserializeTime seconds<br>";
$jsonSize = strlen(json_encode( $test ));
$phpSize = strlen(serialize( $test ));
echo "<p>serialized size : " . strlen(serialize( $test )) . "<br>";
echo "json_encode size : " . strlen(json_encode( $test )) . "<br></p>";
// Compare them
if ( $jsonTime < $serializeTime )
{
echo "json_encode() was roughly " . number_format( ($serializeTime / $jsonTime - 1 ) * 100, 2 ) . "% faster than serialize()";
}
else if ( $serializeTime < $jsonTime )
{
echo "serialize() was roughly " . number_format( ($jsonTime / $serializeTime - 1 ) * 100, 2 ) . "% faster than json_encode()";
} else {
echo 'Unpossible!';
}
echo '<BR>';
// Compare them
if ( $jsonDecodeTime < $unserializeTime )
{
echo "json_decode() was roughly " . number_format( ($unserializeTime / $jsonDecodeTime - 1 ) * 100, 2 ) . "% faster than unserialize()";
}
else if ( $unserializeTime < $jsonDecodeTime )
{
echo "unserialize() was roughly " . number_format( ($jsonDecodeTime / $unserializeTime - 1 ) * 100, 2 ) . "% faster than json_decode()";
} else {
echo 'Unpossible!';
}
echo '<BR>';
// Compare them
if ( $jsonSize < $phpSize )
{
echo "json_encode() string was roughly " . number_format( ($phpSize / $jsonSize - 1 ) * 100, 2 ) . "% smaller than serialize()";
}
else if ( $phpSize < $jsonSize )
{
echo "serialize() string was roughly " . number_format( ($jsonSize / $phpSize - 1 ) * 100, 2 ) . "% smaller than json_encode()";
} else {
echo 'Unpossible!';
}
저도 작은 벤치마크를 만들었어요.과는는똑똑똑똑똑 곳은 위에서 몇 내가 알아차린 곳이야.unserialize
json_decode
unserialize
70%를합니다.json_decode
결론은 아주 간단합니다.한 경우는, 「」를 .json_encode
" "를 unserialize
두 기능을 결합할 수 없기 때문에 성능이 더 필요한 곳을 선택해야 합니다.
유사 벤치마크:
- 몇 개의 랜덤 키와 값을 사용하여 어레이 $arr을 정의합니다.
- x < 100, x++, serialize 및 json_rand의 array_rand에 대해
- y < 1000; y++; json_models 부호화 문자열 - 계산 시간
- y < 1000; y++; 시리얼화된 문자열의 시리얼화 해제 - 계산 시간
- 어느 쪽이 더 빨랐는지 결과를 반영하다
avarage의 경우: unserialize는 json_decode의 4배에 걸쳐 96배로 승리했습니다.2.5ms에 걸쳐 약 1.5ms의 Avarage를 사용합니다.
늦은 건 알지만 답변이 꽤 오래됐기 때문에 방금 PHP 7.4에서 테스트를 했기 때문에 벤치마크에 도움이 될 것 같아서요.
시리얼라이즈/비시리얼라이즈는 JSON보다 훨씬 빠르고 메모리와 공간을 적게 사용하며 PHP 7.4에서 바로 승리하지만 내 테스트가 가장 효율적인지 최선의지 확신할 수 없습니다.
기본적으로 PHP 파일을 만들었습니다.이 파일은, 부호화, 시리얼화, 디코딩, 시리얼화 해제한 어레이를 되돌립니다.
$array = include __DIR__.'/../tests/data/dao/testfiles/testArray.php';
//JSON ENCODE
$json_encode_memory_start = memory_get_usage();
$json_encode_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$encoded = json_encode($array);
}
$json_encode_time_end = microtime(true);
$json_encode_memory_end = memory_get_usage();
$json_encode_time = $json_encode_time_end - $json_encode_time_start;
$json_encode_memory =
$json_encode_memory_end - $json_encode_memory_start;
//SERIALIZE
$serialize_memory_start = memory_get_usage();
$serialize_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$serialized = serialize($array);
}
$serialize_time_end = microtime(true);
$serialize_memory_end = memory_get_usage();
$serialize_time = $serialize_time_end - $serialize_time_start;
$serialize_memory = $serialize_memory_end - $serialize_memory_start;
//Write to file time:
$fpc_memory_start = memory_get_usage();
$fpc_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$fpc_bytes =
file_put_contents(
__DIR__.'/../tests/data/dao/testOneBigFile',
'<?php return '.var_export($array,true).' ?>;'
);
}
$fpc_time_end = microtime(true);
$fpc_memory_end = memory_get_usage();
$fpc_time = $fpc_time_end - $fpc_time_start;
$fpc_memory = $fpc_memory_end - $fpc_memory_start;
//JSON DECODE
$json_decode_memory_start = memory_get_usage();
$json_decode_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$decoded = json_encode($encoded);
}
$json_decode_time_end = microtime(true);
$json_decode_memory_end = memory_get_usage();
$json_decode_time = $json_decode_time_end - $json_decode_time_start;
$json_decode_memory =
$json_decode_memory_end - $json_decode_memory_start;
//UNSERIALIZE
$unserialize_memory_start = memory_get_usage();
$unserialize_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$unserialized = unserialize($serialized);
}
$unserialize_time_end = microtime(true);
$unserialize_memory_end = memory_get_usage();
$unserialize_time = $unserialize_time_end - $unserialize_time_start;
$unserialize_memory =
$unserialize_memory_end - $unserialize_memory_start;
//GET FROM VAR EXPORT:
$var_export_memory_start = memory_get_usage();
$var_export_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$array = include __DIR__.'/../tests/data/dao/testOneBigFile';
}
$var_export_time_end = microtime(true);
$var_export_memory_end = memory_get_usage();
$var_export_time = $var_export_time_end - $var_export_time_start;
$var_export_memory = $var_export_memory_end - $var_export_memory_start;
결과:
Var 내보내기 길이: 11447 시리얼 길이: 11541 Json 부호화 길이: 11895 파일 입력 내용 바이트: 11464
Json 인코딩 시간: 1.9197590351105 시리얼라이즈 시간: 0.160325050354 FPC 시간: 6.2793469429016
Json 인코딩 메모리: 12288 시리얼라이즈 메모리: 12288 FPC 메모리: 0
JSON 디코딩 시간: 1.7493588924408 비시리얼라이즈 시간: 0.19309520721436 Var 내보내기 및 동봉: 3.197413562
JSON 디코딩 메모리: 16384 비시리얼라이즈 메모리: 14360 Var 내보내기 및 동봉: 192
여기서 결과를 확인해 주세요(해킹이 JS 코드 박스에 PHP 코드를 넣은 것에 대해 사과드립니다).
http://jsfiddle.net/newms87/h3b0a0ha/embedded/result/
★★★★★★serialize()
★★★★★★★★★★★★★★★★★」unserialize()
둘 다 다양한 크기의 어레이에서 PHP 5.4가 훨씬 더 빠릅니다.
json_encode vs serialize 및 json_decode vs unserialize를 비교하기 위한 실제 데이터 테스트 스크립트를 만들었습니다.테스트는 실제 가동 중인 전자상거래 사이트의 캐싱 시스템에서 실행되었습니다.캐시에 이미 있는 데이터를 가져와 모든 데이터를 인코딩/디코딩(또는 직렬화/비직렬화)하는 시간을 테스트하면 쉽게 볼 수 있는 테이블에 넣을 수 있습니다.
저는 이것을 PHP 5.4 공유 호스팅 서버에서 실행했습니다.
그 결과, 이러한 대규모에서 소규모 데이터 세트의 시리얼화와 비시리얼화가 확실한 승자라고 할 수 있었습니다.특히 캐싱 시스템에서는 json_decode와 unserialize가 가장 중요합니다.Unserialize는 거의 어디에서나 볼 수 있는 승자였다.보통 json_decode의 2~4배(경우에 따라서는 6~7배)입니다.
@peter-bailey와의 결과 차이를 주목하는 것은 흥미롭다.
다음은 결과를 생성하는 데 사용되는 PHP 코드입니다.
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
function _count_depth($array)
{
$count = 0;
$max_depth = 0;
foreach ($array as $a) {
if (is_array($a)) {
list($cnt, $depth) = _count_depth($a);
$count += $cnt;
$max_depth = max($max_depth, $depth);
} else {
$count++;
}
}
return array(
$count,
$max_depth + 1,
);
}
function run_test($file)
{
$memory = memory_get_usage();
$test_array = unserialize(file_get_contents($file));
$memory = round((memory_get_usage() - $memory) / 1024, 2);
if (empty($test_array) || !is_array($test_array)) {
return;
}
list($count, $depth) = _count_depth($test_array);
//JSON encode test
$start = microtime(true);
$json_encoded = json_encode($test_array);
$json_encode_time = microtime(true) - $start;
//JSON decode test
$start = microtime(true);
json_decode($json_encoded);
$json_decode_time = microtime(true) - $start;
//serialize test
$start = microtime(true);
$serialized = serialize($test_array);
$serialize_time = microtime(true) - $start;
//unserialize test
$start = microtime(true);
unserialize($serialized);
$unserialize_time = microtime(true) - $start;
return array(
'Name' => basename($file),
'json_encode() Time (s)' => $json_encode_time,
'json_decode() Time (s)' => $json_decode_time,
'serialize() Time (s)' => $serialize_time,
'unserialize() Time (s)' => $unserialize_time,
'Elements' => $count,
'Memory (KB)' => $memory,
'Max Depth' => $depth,
'json_encode() Win' => ($json_encode_time > 0 && $json_encode_time < $serialize_time) ? number_format(($serialize_time / $json_encode_time - 1) * 100, 2) : '',
'serialize() Win' => ($serialize_time > 0 && $serialize_time < $json_encode_time) ? number_format(($json_encode_time / $serialize_time - 1) * 100, 2) : '',
'json_decode() Win' => ($json_decode_time > 0 && $json_decode_time < $serialize_time) ? number_format(($serialize_time / $json_decode_time - 1) * 100, 2) : '',
'unserialize() Win' => ($unserialize_time > 0 && $unserialize_time < $json_decode_time) ? number_format(($json_decode_time / $unserialize_time - 1) * 100, 2) : '',
);
}
$files = glob(dirname(__FILE__) . '/system/cache/*');
$data = array();
foreach ($files as $file) {
if (is_file($file)) {
$result = run_test($file);
if ($result) {
$data[] = $result;
}
}
}
uasort($data, function ($a, $b) {
return $a['Memory (KB)'] < $b['Memory (KB)'];
});
$fields = array_keys($data[0]);
?>
<table>
<thead>
<tr>
<?php foreach ($fields as $f) { ?>
<td style="text-align: center; border:1px solid black;padding: 4px 8px;font-weight:bold;font-size:1.1em"><?= $f; ?></td>
<?php } ?>
</tr>
</thead>
<tbody>
<?php foreach ($data as $d) { ?>
<tr>
<?php foreach ($d as $key => $value) { ?>
<?php $is_win = strpos($key, 'Win'); ?>
<?php $color = ($is_win && $value) ? 'color: green;font-weight:bold;' : ''; ?>
<td style="text-align: center; vertical-align: middle; padding: 3px 6px; border: 1px solid gray; <?= $color; ?>"><?= $value . (($is_win && $value) ? '%' : ''); ?></td>
<?php } ?>
</tr>
<?php } ?>
</tbody>
</table>
먼저 스크립트를 변경하여 벤치마킹을 몇 가지 더 수행(또한 1회 실행이 아닌 1,000회 실행)했습니다.
<?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);
$totalJsonTime = 0;
$totalSerializeTime = 0;
$totalJsonWins = 0;
for ($i = 0; $i < 1000; $i++) {
// Time json encoding
$start = microtime(true);
$json = json_encode($testArray);
$jsonTime = microtime(true) - $start;
$totalJsonTime += $jsonTime;
// Time serialization
$start = microtime(true);
$serial = serialize($testArray);
$serializeTime = microtime(true) - $start;
$totalSerializeTime += $serializeTime;
if ($jsonTime < $serializeTime) {
$totalJsonWins++;
}
}
$totalSerializeWins = 1000 - $totalJsonWins;
// Compare them
if ($totalJsonTime < $totalSerializeTime) {
printf("json_encode() (wins: $totalJsonWins) was roughly %01.2f%% faster than serialize()\n", ($totalSerializeTime / $totalJsonTime - 1) * 100);
} else {
printf("serialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than json_encode()\n", ($totalJsonTime / $totalSerializeTime - 1) * 100);
}
$totalJsonTime = 0;
$totalJson2Time = 0;
$totalSerializeTime = 0;
$totalJsonWins = 0;
for ($i = 0; $i < 1000; $i++) {
// Time json decoding
$start = microtime(true);
$orig = json_decode($json, true);
$jsonTime = microtime(true) - $start;
$totalJsonTime += $jsonTime;
$start = microtime(true);
$origObj = json_decode($json);
$jsonTime2 = microtime(true) - $start;
$totalJson2Time += $jsonTime2;
// Time serialization
$start = microtime(true);
$unserial = unserialize($serial);
$serializeTime = microtime(true) - $start;
$totalSerializeTime += $serializeTime;
if ($jsonTime < $serializeTime) {
$totalJsonWins++;
}
}
$totalSerializeWins = 1000 - $totalJsonWins;
// Compare them
if ($totalJsonTime < $totalSerializeTime) {
printf("json_decode() was roughly %01.2f%% faster than unserialize()\n", ($totalSerializeTime / $totalJsonTime - 1) * 100);
} else {
printf("unserialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than json_decode()\n", ($totalJsonTime / $totalSerializeTime - 1) * 100);
}
// Compare them
if ($totalJson2Time < $totalSerializeTime) {
printf("json_decode() was roughly %01.2f%% faster than unserialize()\n", ($totalSerializeTime / $totalJson2Time - 1) * 100);
} else {
printf("unserialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than array json_decode()\n", ($totalJson2Time / $totalSerializeTime - 1) * 100);
}
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';
}
저는 이 PHP 7 빌드를 사용했습니다.
PHP 7.0.14 (cli) (구축: 2017년 1월 18일 19:13:23) (NTS) Copyright (c) 1997-2016 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies with Zend OPcache v7.0.14, Copyright (cyright) 1999-2016, Zend Technologies by.
결과는 다음과 같습니다.
serialize()는 json_serialize()보다 약 10.98% 빨랐습니다(987), json_serialize()보다 약 33.26% 빨랐습니다(987), 어레이 json_serialize()보다 약 48.35% 빨랐습니다.
즉, serialize/unserialize가 가장 빠른 방법이며, json_encode/decode가 가장 이식성이 높습니다.
비 PHP 시스템과 송수신하는 것보다 10배 이상 자주 시리얼화된 데이터를 읽고 쓰는 시나리오를 고려할 경우, 여전히 시리얼화/비시리얼화를 사용하여 시리얼화 전에 json_encode 또는 json_decode를 사용하는 것이 좋습니다.
어레이에 대해 .JSON 포맷은 하지 않습니다.json_decode()
이치노
$config = array(
'Frodo' => 'hobbit',
'Gimli' => 'dwarf',
'Gandalf' => 'wizard',
);
print_r($config);
print_r(json_decode(json_encode($config)));
출력:
Array
(
[Frodo] => hobbit
[Gimli] => dwarf
[Gandalf] => wizard
)
stdClass Object
(
[Frodo] => hobbit
[Gimli] => dwarf
[Gandalf] => wizard
)
just fyi -- JSON과 같이 읽기 쉽고 이해하기 쉬운 것으로 데이터를 시리얼화 하고 싶다면 메시지 팩을 체크해야 합니다.
데이터를 백업하고 다른 컴퓨터에 복원하거나 FTP를 통해 복원하려는 경우 JSON이 더 좋습니다.
예를 들어 serialize를 사용하면 데이터를 Windows 서버에 저장하고 FTP를 통해 데이터를 다운로드하여 Linux 서버에서 복원할 수 있습니다.serialize는 문자열의 길이를 저장하고 Unicode > UTF-8에서는 1바이트의 문자 변환이2바이트가 되어 알고리즘이 크래쉬 할 수 있기 때문입니다.
THX - 이 벤치마크 코드의 경우:
0.。JSON 0.0031511783599854입니다.
가 0.0037961006164551초(PHP)
json_encode()
빨랐다.serialize()
.0070841312408447로
PHP ( 0 . 0035839080810547 )
unserialize()
.66%로 97.json_encode()
따라서 - 자신의 데이터로 테스트합니다.
여기서 말하는 내용을 요약하면 json_decode/encode가 serialize/unserialize보다 빠른 것 같지만 var_dump를 실행하면 serialize 객체의 유형이 변경됩니다.어떤 이유로든 유형을 유지하고 싶다면 serialize를 선택하십시오.
(예를 들어 stdClass vs array)
serialize/unserialize:
Array cache:
array (size=2)
'a' => string '1' (length=1)
'b' => int 2
Object cache:
object(stdClass)[8]
public 'field1' => int 123
This cache:
object(Controller\Test)[8]
protected 'view' =>
json 부호화/복호화
Array cache:
object(stdClass)[7]
public 'a' => string '1' (length=1)
public 'b' => int 2
Object cache:
object(stdClass)[8]
public 'field1' => int 123
This cache:
object(stdClass)[8]
보시다시피 json_encode/decode는 모든 것을 stdClass로 변환합니다.이것은 그다지 좋지 않습니다.오브젝트 정보가 손실됩니다.필요에 따라 결정하십시오.특히 어레이뿐만 아니라...
슈퍼캐시를 사용하지 않는Cache를 하는 것이 .슈퍼 캐시json_encode
★★★★★★★★★★★★★★★★★」serialize
다른 PHP 캐시 메커니즘에 비해 사용하기 쉽고 매우 빠릅니다.
https://packagist.org/packages/smart-php/super-cache
예:
<?php
require __DIR__.'/vendor/autoload.php';
use SuperCache\SuperCache as sCache;
//Saving cache value with a key
// sCache::cache('<key>')->set('<value>');
sCache::cache('myKey')->set('Key_value');
//Retrieving cache value with a key
echo sCache::cache('myKey')->get();
?>
언급URL : https://stackoverflow.com/questions/804045/preferred-method-to-store-php-arrays-json-encode-vs-serialize
'source' 카테고리의 다른 글
vuex에서 '정의되지 않은' 값을 수정하는 방법 (0) | 2023.01.19 |
---|---|
DDoS 보호를 활성화하는 방법 (0) | 2023.01.19 |
MySQL에 저장된 프로시저에서 디버깅 정보 인쇄 (0) | 2023.01.19 |
여러 문자열을 여러 문자열로 바꿉니다. (0) | 2023.01.19 |
exclipse - 테이블의 JPA 엔티티, 스키마가 나열되지 않음 (0) | 2023.01.19 |