보통 PHP에서 한글 글자수를 센다던가, substr을 통해 자른다던가, 한글자씩 분리한다던가 할 때 php-mbstring 확장을 사용한다.
만약 자신이 만들고 있는 PHP 앱이 빠른 속도를 요구한다면, mbstring 확장을 떨쳐 내는 것은 이를 위한 좋은 방법이 될 수 있다. 실제로 해외의 여러 커뮤니티에서도 mb_strlen() 등은 매우 느리다고 이야기하고 있고, 그래서 구글링 끝에 얻은 대안 두 개를 소개한다.
1. iconv_
php-iconv 모듈에 속해 있는데 대부분 내장이라 뭘 따로 설치할 필요는 없다.
<?php
$str = '가나다';
echo microtime();
for($i=0; $i<1000; ++$i){
mb_strlen($str);
}
echo microtime();
echo microtime();
for($i=0; $i<1000; ++$i){
iconv_strlen($str);
}
echo microtime();
echo microtime();
for($i=0; $i<1000; ++$i){
count(preg_split('//u', $str));
}
echo microtime();
속도를 측정해 보고 싶어서 다음과 같이 코드를 작성 후 실행하였다.
strlen을 측정하는 세 가지 방법을 사용하였다. 각 방법으로 1000회씩 실시해 그 소요시간의 차를 구해보겠다.
출력
0.15499200 1620953054
0.15879300 1620953054
0.15879800 1620953054
0.15966200 1620953054
0.15966400 1620953054
0.16053900 1620953054
분석해 보면, mb_strlen()은 0.003801초
iconv_strlen()은 0.000864초
count(preg_split(...))은 0.000875초가 걸렸다.
물론 하단에 서술하겠지만 count(preg_split()) 은 함수를 하나 더 써야해서 속도가 더 느릴 것이다.
이렇게 해 보면 mb_strlen이 얼마나 느린 함수인지 알 수 있다.
2. preg_split
출처:
stackoverflow.com/questions/3666306/how-to-iterate-utf-8-string-in-php
<?php
function u_strlen($text){
$result = array_slice(preg_split('//u', $text), 1, -2);
return count($result);
}
function u_substr($text, $offset, $len=null){
$result = preg_split('//u', $text,-1,PREG_SPLIT_NO_EMPTY);
return array_slice($result, $offset, $len);
}
function u_strpos($haystatck, $needle, $offset=0){
$split = preg_split('//u', $haystack,-1,PREG_SPLIT_NO_EMPTY);
$result = array_slice($result, $offset);
return array_search($needle, $result);
}
$sample = '다람쥐 헌 쳇바퀴에 타고파';
echo u_strlen($sample); // 14
echo u_substr($sample, 1); // 람쥐 헌 쳇바퀴에 타고파
echo u_strpos($sample, '쳇바퀴'); // 6
정규식 함수를 쓰기 때문에 얼핏 보면 느려보일 수 있다. 그러나 메모리를 더 많이 먹을지언정 속도는 더 빨라졌다는 것이 해당 stackoverflow 페이지의 주 내용이다.
여기서 주의할 점은, PREG_SPLIT_NO_EMPTY 옵션을 주지 않으면 맨 앞과 맨 뒤에 공백이 생긴다.
'World Wide Web > PHP Lecture' 카테고리의 다른 글
[PHP 8] 시작과 끝 문자열 확인하기 - str_starts_with(), str_ends_with() (0) | 2021.03.18 |
---|---|
PHP Lecture 2 - 변수 (0) | 2020.11.13 |
PHP Lecture 1 - 시작 (0) | 2020.10.23 |