조금 더 빠른 mb_strlen 구현

mb_strlen을 구현해야 할 일이 생겨서 검색하던 도중 좋은 코드를 찾았습니다.

/**
 * Fallback implementation of mb_strlen, hardcoded to UTF-8.
 * @param string $str
 * @param string $enc optional encoding; ignored
 * @return int
 */
function new_mb_strlen( $str, $enc="" ) {
	$counts = count_chars( $str );
	$total = 0;

	// Count ASCII bytes
	for( $i = 0; $i < 0x80; $i++ ) {
		$total += $counts[$i];
	}

	// Count multibyte sequence heads
	for( $i = 0xc0; $i < 0xff; $i++ ) {
		$total += $counts[$i];
	}
	return $total;
}

그런데 조금 더 수정할 수 있을 것만 같아서 여러가지 시도를 해보았습니다. 결국 위 코드를 다음과 같이 수정할 수 있었습니다.

/**
 * Fallback implementation of mb_strlen, hardcoded to UTF-8.
 * @param string $str
 * @param string $enc optional encoding; ignored
 * @return int
 */
function newer_mb_strlen( $str ) {
	$counts = count_chars($str);
	for($i = 0x80; $i < 0xc0; $i++) {
		unset($counts[$i]);
	}
	return array_sum($counts);
}

하나하나 카운트하는 대신 불필요한 영역을 제거해버리고 내장 함수 array_sum을 사용해 합산했습니다. 벤치 마크 코드에 위 함수를 추가한 후 실행해 본 결과 다음과 같은 결과를 얻을 수 있었습니다. 단, 텍스트 파일은 제공되지 않았기 때문에 임의로 young.txt 파일을 작성해 여러차례 실행했습니다.

Testing young.txt:
              strlen       2582 chars    0.010ms
           mb_strlen       2462 chars    0.025ms
       old_mb_strlen       2462 chars    2.698ms
       new_mb_strlen       2462 chars    0.197ms
     newer_mb_strlen       2462 chars    0.117ms

Testing young.txt:
              strlen       2582 chars    0.012ms
           mb_strlen       2462 chars    0.024ms
       old_mb_strlen       2462 chars    2.908ms
       new_mb_strlen       2462 chars    0.190ms
     newer_mb_strlen       2462 chars    0.096ms

Testing young.txt:
              strlen       2582 chars    0.009ms
           mb_strlen       2462 chars    0.023ms
       old_mb_strlen       2462 chars    2.681ms
       new_mb_strlen       2462 chars    0.200ms
     newer_mb_strlen       2462 chars    0.116ms

Testing young.txt:
              strlen       2582 chars    0.010ms
           mb_strlen       2462 chars    0.025ms
       old_mb_strlen       2462 chars    2.685ms
       new_mb_strlen       2462 chars    0.205ms
     newer_mb_strlen       2462 chars    0.106ms

댓글을 남겨주세요