From c4db6e7751f55249e8bbf3e0d689c6347ceee3b4 Mon Sep 17 00:00:00 2001 From: thisgun Date: Tue, 7 Apr 2026 10:42:55 +0000 Subject: [PATCH] =?UTF-8?q?[perf]cut=5Fstr()=20=EB=A9=94=EB=AA=A8=EB=A6=AC?= =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=EB=9F=89=EA=B3=BC=20CPU=20=EC=98=A4?= =?UTF-8?q?=EB=B2=84=ED=97=A4=EB=93=9C=20=EA=B0=90=EC=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 구현은 preg_split("//u")로 입력 문자열의 모든 문자를 PHP 배열로 분해한 뒤 count/array_slice/join 3단계로 처리하여, 짧은 문자열이든 긴 문자열이든 항상 문자 수만큼 배열 원소를 할당하고 regex를 호출함. 게시글 목록의 제목/내용 표시 등 페이지당 수십~수백 회 호출되는 핫패스에서 불필요한 오버헤드를 발생시킴. 개선: 1. 바이트 길이 빠른 경로: strlen(str) <= len이면 UTF-8 특성상 문자 수도 보장되므로 즉시 반환. ASCII/짧은 제목은 mb_strlen 호출 없이 종료. 2. mbstring 확장 사용: mb_strlen + mb_substr로 배열 생성 없이 상수 메모리로 길이 체크/절단 처리. 3. preg_split 기반 기존 로직은 mbstring 미설치 환경 폴백으로 유지. 의미론적 동등성 유지 (잘라낸 결과와 suffix 부착 조건 모두 동일). --- lib/common.lib.php | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/common.lib.php b/lib/common.lib.php index 106873660..646ee91f6 100644 --- a/lib/common.lib.php +++ b/lib/common.lib.php @@ -1743,18 +1743,27 @@ function view_link($view, $number, $attribute) function cut_str($str, $len, $suffix="…") { - $arr_str = preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY); - $str_len = count($arr_str); - - if ($str_len >= $len) { - $slice_str = array_slice($arr_str, 0, $len); - $str = join("", $slice_str); - - return $str . ($str_len > $len ? $suffix : ''); - } else { - $str = join("", $arr_str); + // 빠른 경로: 바이트 길이가 이미 제한 이내라면 문자 수 계산 불필요 + // UTF-8의 모든 문자는 최소 1바이트이므로 bytes <= len이면 chars <= len이 보장됨 + if (strlen($str) <= $len) { return $str; } + + // mbstring 확장 사용 (PHP 4.0.6+ 기본 내장): 문자 배열 생성 없이 길이/슬라이스 처리 + if (function_exists('mb_strlen')) { + if (mb_strlen($str, 'UTF-8') > $len) { + return mb_substr($str, 0, $len, 'UTF-8') . $suffix; + } + return $str; + } + + // mbstring 미설치 환경 폴백 (기존 동작 유지) + $arr_str = preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY); + $str_len = count($arr_str); + if ($str_len > $len) { + return join("", array_slice($arr_str, 0, $len)) . $suffix; + } + return join("", $arr_str); }