鍍金池/ 問(wèn)答/PHP/ php加載大數(shù)組 require 問(wèn)題

php加載大數(shù)組 require 問(wèn)題

最近做分詞,詞庫(kù)我是保存的一個(gè)大數(shù)組,用做測(cè)試的詞庫(kù)14w個(gè)詞。

方法一 require進(jìn)來(lái)

詞庫(kù)文件 dict.php

<?php
//返回一個(gè)多維的大數(shù)組 這個(gè)文件大概5.3M
return array();

分詞文件文件 word.php

<?php
$time = microtime(true);
$memory = memory_get_usage();
$dict = require('dict.php');
//require include  都測(cè)試了差不多
echo '耗時(shí):'.(microtime(true) - $time).PHP_EOL; 
//這里輸出0.4左右
echo '內(nèi)存:'.(memory_get_usage() - $memory).PHP_EOL; 
//這里輸出144105672

直接包含一個(gè)數(shù)組文件居然這么耗時(shí)。

方法二直接訪問(wèn)

結(jié)果:直接通過(guò)url訪問(wèn)http://host/dict.php 非常快。
我把dict.php修改了一下

<?php
//$arr一個(gè)多維的大數(shù)組 這個(gè)文件大概5.3M
$time = microtime(true);
$arr = array();
echo '耗時(shí):'.(microtime(true) - $time).PHP_EOL;
//通過(guò)url直接訪問(wèn)這個(gè)文件 這里輸出 0.0001左右 居然這么快

方法三通過(guò)json反序列化得到

我再用json測(cè)試了一下
我把詞典文件通過(guò)json_encode保存到了dict.json
然后在 word.php 修改如下

<?php
$time = microtime(true);
$memory = memory_get_usage();
$dict = json_decode(file_get_contents('dict.json'),true);
echo '耗時(shí):'.(microtime(true) - $time).PHP_EOL; 
//這里輸出0.2左右
echo '內(nèi)存:'.(memory_get_usage() - $memory).PHP_EOL; 
//這里輸出144105672

出乎意外的發(fā)生了 通過(guò)json序列號(hào)和反序列化生成的數(shù)組居然比直接包含進(jìn)來(lái)還要快。

請(qǐng)幫我分析分析什么原因?

我的環(huán)境 apache + php7.0.11

回答
編輯回答
短嘆

require和file_get_contents讀取的文件目標(biāo)的區(qū)域是不一致的,好比java的堆外和堆內(nèi)。。

2017年10月18日 10:52
編輯回答
舊酒館

require是按塊大小讀取到內(nèi)存,循環(huán)讀取
file_get_contents是按目標(biāo)源讀取到內(nèi)存映射
響應(yīng)速度上當(dāng)然是file_get_contents更快

2018年4月28日 17:44
編輯回答
筱饞貓

require讀取的機(jī)制是以8192字節(jié)大小的buffer循環(huán)將文件讀入內(nèi)存 大文件 require 需要一直循環(huán)調(diào)用,
file_get_contents 讀取文件 是內(nèi)存映射,直接將文件映射到虛擬內(nèi)存里,所以更快。

2018年5月17日 18:58