Списки уникальных строковых значений

Задача, которая недавно стояла передо мной: содержать список уникальных строковых значений, пополнять его и проверять, есть ли в списке какое-то конкретное значение. Такая задача вряд ли может возникнуть при правильном проектировании на несложных сайтах. Потребность может возникнуть, например, в демонизированных скриптах.

Сразу мне в голову пришло четыре сходных решения (я не включил сюда альтернативу БД).

  • Первые два способа заключаются в том, чтобы строки хранить в значениях массива. Проверять наличие строки функцией:
    • 1. array_search()
    • 2. in_array()
  • Последние два предусматривают хранение строк в ключах массива. Проверять их наличие:
    • 3. isset()
    • 4. array_key_exists()

Чтобы не тратить много времени, я быстро написал тест для всех четырех способов, который дал следующий результат:

array_search():

6.5036978721619
6.4741249084473
6.5003960132599
6.4547579288483

in_array()

6.4824228286743
6.232085943222
6.5026969909668
6.559093952179

isset()

0.03310489654541
0.037132978439331
0.042035818099976
0.03764009475708

array_key_exists()

0.049704074859619
0.045562028884888
0.045705080032349
0.045676946640015

Для тестов использовалась одна тестирующая функция (принимающая массив и имя функции, проверяющей наличие значения) и отдельные сессии php-интерпритатора.
Тестирующий код:

test.php
<a href=»?t=a»>array_search()</a><br />
<a href=»?t=b»>in_array()</a><br />
<a href=»?t=c»>isset()</a><br />
<a href=»?t=d»>array_key_exists()</a><br />
<?php
function onListA($list$val) {
    return 
false !== array_search(md5($val), $list);
}
function 
onListB($list$val) {
    return 
in_array(md5($val), $list);
}
function 
onListC($list$key) {
    return isset(
$list[md5($key)]);
}
function 
onListD($list$key) {
    return 
array_key_exists(md5($key), $list);
}
define(‘COUNT’30000);
function 
prepareAB() {
    
$result = array();
    for (
$i 0$i COUNT/10;) {
        
$result[] = md5(++$i);
        
$result[] = md5(++$i);
        
$result[] = md5(++$i);
        
$result[] = md5(++$i);
        
$result[] = md5(++$i);
        
$result[] = md5(++$i);
        
$result[] = md5(++$i);
        
$result[] = md5(++$i);
        
$result[] = md5(++$i);
        
$result[] = md5(++$i);
    }
    return 
$result;
}
function 
prepareBC() {
    
$result = array();
    for (
$i 0$i COUNT/10;) {
        
$result[md5(++$i)] = 0;
        
$result[md5(++$i)] = 0;
        
$result[md5(++$i)] = 0;
        
$result[md5(++$i)] = 0;
        
$result[md5(++$i)] = 0;
        
$result[md5(++$i)] = 0;
        
$result[md5(++$i)] = 0;
        
$result[md5(++$i)] = 0;
        
$result[md5(++$i)] = 0;
        
$result[md5(++$i)] = 0;
    }
    return 
$result;
}
function 
microtime_float()
{
    list(
$usec$sec) = explode(» «microtime());
    return ((float)
$usec + (float)$sec);
}
function 
test($func$array) {
    
$time_start microtime_float();
    for (
$i 0$i COUNT; ++$i) {
        
$func($array$i);
    }
    
$time_end microtime_float();
    echo 
$time_end — $time_start;
}
switch (
$_GET[‘t’]?$_GET[‘t’]:‘a’) {
    case 
‘a’test(‘onListA’prepareAB()); break;
    case 
‘b’test(‘onListB’prepareAB()); break;
    case 
‘c’test(‘onListC’prepareBC()); break;
    default : 
test(‘onListD’prepareBC());
}
?>

Думаю, результаты теста говорят сами за себя.

Реклама
Запись опубликована в рубрике php. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s