如何在PHP中高效统计字符元组(N-grams)?
高效统计大文件/字符串中字符元组(N-grams)的PHP方案需求
在某PHP文件分类项目中,需要快速统计10MB至1GB+大文件/字符串中的字符元组(即N-grams),目前存在以下现状:
现有单字符(N=1)高效实现
基于PHP内置函数count_chars()实现,处理十亿级字符仅需0.x秒,效率极高:
// 返回关联数组 [字符 => 出现次数] function frequencies($txt) { $index = count_chars($txt, 1); foreach ($index as $code => $nb) { $count[chr($code)] = $nb; } return $count; }
自定义多字符元组(N≥2)的低效实现
自行编写的N元组统计代码效率极低:
通用N元组实现
// 返回关联数组 [字符元组 => 出现次数] function frequencies($txt, $n) { $length = strlen($txt) - $n + 1; for ($i = 0; $i < $length; $i++) { @$count[substr($txt, $i, $n)]++; } return $count; } // 注:使用'@'虽不优雅,但比isset()判断更快
该实现N=1时耗时约45秒(比内置实现慢100倍),N=2时耗时超1分钟。
二元组(N=2)优化尝试
尝试直接字符拼接的实现,仅略快(耗时约42秒),仍远不及内置函数效率:
function twograms($txt) { $length = strlen($txt) - $n; for ($i = 0; $i < $length; $i++) { @$count[$txt[$i] . $txt[$i+1]]++; } return $count; }
现寻求更高效的字符元组统计方案,已补充str_split与array_count_values组合方案及内存占用测试。
内容的提问来源于stack exchange,提问作者Crypto
相关产品推荐
相关产品推荐

