⬆️ ⬇️

Unserialize performance

PHP has two great functions, serialize and unserialize. The first converts almost any data set to a string, the second performs the inverse transformation. These functions are useful when organizing caching or storing sessions in a database. I found that the running time of the unserialize function may be unexpectedly large.



I will not describe how and why I needed to serialize and deserialize a large array of data, it is much more interesting to look at what I discovered.

  1. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  2. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  3. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  4. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  5. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  6. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  7. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  8. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  9. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  10. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  11. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  12. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;
  13. <?php ini_set ( 'memory_limit' , '512M' ) ; $file = '/tmp/1' ; $data = range ( 1 , 2000000 ) ; echo "Test serialize \n " ; $time0 = microtime ( 1 ) ; file_put_contents ( $file , serialize ( $data ) ) ; $time1 = microtime ( 1 ) ; unserialize ( file_get_contents ( $file ) ) ; $time2 = microtime ( 1 ) ; $timeset = $time1 - $time0 ; $timeget = $time2 - $time1 ; echo "Serialize set time $timeset get time $timeget \n " ;


  Test serialize
 Serialize set time 1.35619807243 get time 31.1126699448




30 seconds to deserialize! This result just shocked me. First, I checked that file_get_contents does not affect the result of the execution. Then I looked at the performance of json_encode and json_decode (JSON set time 0.270335912704 get time 1.30652809143). “Everything is stranger and stranger,” I thought, and decided to plot the unserialize function as a function of the length of the array being deserialized.





')

The graph clearly shows the quadratic (!) Dependence of the execution time of a function on the length of the array. This is the unexpectedly slow unserialize built-in function.



The situation, of course, is not critical. You can use other methods of serialization and deserialization. The main purpose of the article is to show how the performance of the unserialize function depends on the size of the data.



Source codes for checking results can be found at http://alexxz.ru/habr/unserialize_benchmark.tar.gz



Used software and hardware PHP 5.3.2

Linux ubuntu 2.6.32–24-generic (10.4)

Intel® Core 2 CPU 6600 @ 2.40GHz



______________________

The text was prepared in the Blog Editor from © SoftCoder.ru

Source: https://habr.com/ru/post/104069/



All Articles