php: startWith и endWith. Ищем самый производительный вариант

 
+
-
edit
 

Balancer

администратор
★★★★☆
Часто нужно определить начинается ли или заканчивается ли строка заданной подстрокой. В PHP встроенных startWith и endWith нет. Реализовать их можно множеством разных способов. Вот результат поиска самого быстрого варианта. Тестирование в один поток, 100 тыс. циклов с одним совпадающим и одним несовпадающим вариантом. php-5.3.3, Q6600, 32 бита. Приводится время всего теста (т.е. 200 тыс. проверок)

Сперва на проверку начала строки. Разные варианты в порядке итогового быстродействия.

0.45сек.
code php
  1. function startsWith_pos($haystack, $needle, $case=true)
  2. {
  3.    if($case)
  4.        return strpos($haystack, $needle, 0) === 0;
  5.  
  6.    return stripos($haystack, $needle, 0) === 0;
  7. }


0.67сек
code php
  1. function startsWith_sub($string, $char)
  2. {
  3.     $length = strlen($char);
  4.     return (substr($string, 0, $length) === $char);
  5. }


0.68
code php
  1. function startsWith_cmprev($haystack, $needle, $case=true)
  2. {
  3.     if ($case)
  4.         return strncmp($haystack, $needle, strlen($needle)) == 0;
  5.     else
  6.         return strncasecmp($haystack, $needle, strlen($needle)) == 0;
  7. }



0.74
code php
  1. function startsWith_re($haystack, $needle)
  2. {
  3.     return preg_match('/^'.preg_quote($needle)."/", $haystack);
  4. }


0.91
code php
  1. function startsWith_cmp1($haystack, $needle, $case=true)
  2. {
  3.     if($case)
  4.         return strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0;
  5.  
  6.     return strcasecmp(substr($haystack, 0, strlen($needle)), $needle) === 0;
  7. }
 
+
-
edit
 

Balancer

администратор
★★★★☆
Теперь — варианты на проверку окончания строки:

0.71
code php
  1. function endsWith_sub($string, $char)
  2. {
  3.     $length = strlen($char);
  4.     return (substr($string, -$length, $length) === $char);
  5. }


0.73
code php
  1. function endsWith_re($haystack, $needle)
  2. {
  3.     return preg_match("/".preg_quote($needle) .'$/', $haystack);
  4. }


0.92
code php
  1. function endsWith_pos($haystack, $needle, $case=true)
  2. {
  3.   $expectedPosition = strlen($haystack) - strlen($needle);
  4.  
  5.   if($case)
  6.       return strrpos($haystack, $needle, 0) === $expectedPosition;
  7.  
  8.   return strripos($haystack, $needle, 0) === $expectedPosition;
  9. }


1.12
code php
  1. function endsWith_cmp1($haystack, $needle, $case=true)
  2. {
  3.     if($case)
  4.         return strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0;
  5.  
  6.     return strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0;
  7. }


1.33
code php
  1. function endsWith_cmprev($haystack, $needle, $case=true)
  2. {
  3.      return startsWith_cmprev(strrev($haystack),strrev($needle),$case);
  4. }
 
RU bjaka_max #25.04.2011 23:05  @Balancer#25.04.2011 17:23
+
-
edit
 

bjaka_max

втянувшийся

Balancer> Теперь — варианты на проверку окончания строки:
Balancer> 0.71

function endsWith_sub($string, $char)
function endsWith_re($haystack, $needle)
- case не задаётся, если добавить его то у меня endsWith_sub чуть чуть медленнее, чем endsWith_cmp1 становится

$case=false

endsWith_cmp1
0.30
endsWith_re
0.32
endsWith_sub
0.22

$case=true

endsWith_cmp1
0.31
endsWith_re
0.33
endsWith_sub
0.33

code text
  1. function endsWith_sub($string, $char, $case=true)
  2. {
  3.     $length = strlen($char);
  4.     if($case)
  5.                 return (strtolower(substr($string, -$length, $length)) === strtolower($char));
  6.     return (substr($string, -$length, $length) === $char);
  7. }
  8. function endsWith_re($haystack, $needle, $case=true)
  9. {
  10.     return preg_match("/".preg_quote($needle) .'$/'.($case?'i':''), $haystack);
  11. }

может чего накосячил.

Ага, утром глянул на свежую голову: наоборот должно быть
code text
  1. function endsWith_sub($string, $char, $case=true)
  2. {
  3.     $length = strlen($char);
  4.     if($case)
  5.          return (substr($string, -$length, $length) === $char);
  6.     return (strtolower(substr($string, -$length, $length)) === strtolower($char));
  7. }
  8. function endsWith_re($haystack, $needle, $case=true)
  9. {
  10.         if($case)
  11.                 return preg_match('/'.preg_quote($needle) .'$/', $haystack);
  12.         return preg_match('/'.preg_quote($needle) .'$/i', $haystack);
  13. }

впрочем смысл такой-же.
 1010
Это сообщение редактировалось 26.04.2011 в 06:55

Последние действия над темой

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru