Оптимизиране на код за засичане на лоши думи в текст

dakata__92

Super Moderator
Здравейте. Можем ли да оптимизираме кода да работи по-бързо и надеждно?

PHP:
private function checkBadWords(): bool
{
$message = $this->smsInfo['message'];
    if ($this->user->checkMessage() == 0 || empty($message)) {
return false;
    }
$sql = "SELECT * FROM badWords";
    $cacheKey = 'BAD-WORDS-' . md5($sql);
    $badWordsArray = MC::get($cacheKey, 1);
    if (!is_array($badWordsArray)) {
$badWordsArray = [];
        $query = db::query($sql);
        if ($query->num_rows > 0) {
while ($row = $query->fetch_assoc()) {
$caseInsensitiveWord = mb_strtolower($row['word']);
                $badWordsArray[$caseInsensitiveWord] = $row['id'];
            }
        }
MC::set($cacheKey, $badWordsArray, MEMCACHE_COMPRESSED, 3600, 1);
    }
if (count($badWordsArray) <= 0) {
return false;
    }
$space = ' ';
    $message = preg_replace('/\s+/u', $space, $message);
    $messageWords = explode($space, trim($message));
    foreach ($messageWords as $word) {
if (is_numeric($word) || mb_strlen($word) <= 2) {
continue;
        }
$caseInsensitiveWord = mb_strtolower($word);
        if (isset($badWordsArray[$caseInsensitiveWord])) {
return true;
        }
    }
return false;
}
 
Последно редактирано:
Ей тая проверка може да е по-проста, защото memcached връща false, ако няма нищо в кеша. Ще спестиш малко време.

Код:
 if ($badWordsArray === false)

Също така ако си направиш регуларния израз да е '/\s+/' вместо '/\s+/u' печелиш малко време.. Поне според моите тестове. Като цяло това май даже работи една идея по-бързо, вместо preg_replace и explode, като тествам..

Код:
$messageWords = preg_split('/\s+/', $test);

Можеш да използваш Redis вместо memcached за още малко бързинка :D
 
Последно редактирано:
Аз също бих махнал preg_replace или preg_split. Те са принципно по-бавни. expolode() дори и да извади още един елемент, защото е имало 2 спейса някъде е без значение. Така или иначе в цикъла долу ще пропуснеш такива елементи, заради mb_strlen() <= 2 .
Извъртане на допълнителен празен елемент според мен спестява повече процесорно време отколкото компилиране на регулярен израз.

Заявката трябва ли ти да извиква всички колони? Ако са само двете id и word, то тогава няма много значение. Въпреки това не виждам смисъл от ваденето на id от базата данни. Не се използва за нищо освен да го запазиш тук:

PHP:
$badWordsArray[$caseInsensitiveWord] = $row['id'];

Понеже стойността не я използваш, лесно можеш да замениш $row['id'] с просто единица или булева стойност. Така си спестяваш да вадиш излишна информация от базата данни и да използваш нещо, което не предава никаква стойност (поне не виждам да придава в текущия контекст).
 

Back
Горе