Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   Что будет быстрее работать?(теория) (https://forum.antichat.xyz/showthread.php?t=90588)

EST a1ien 05.11.2008 23:56

Что будет быстрее работать?(теория)
 
Есть некая структура файлов(котороя не обновляется и не изменяется, просто папки и файлы).
Мне надо реализовать навигацию по этим файлам. Просто включить Options +Indexes не устраивает.

Собственно что будет быстрее работать.
Если мы загоним весь список файлов в базу(не сами файлы а просто их иерархию) и будем просто вытаскивать из базы.
Или будем через system('ls') ползать?

Или еще чтонибудь предложите?

ЗЫ пока писал вспомнил про opendir/readdir. он наверно будет быстрее?

Chaak 06.11.2008 00:04

База медленная штука. Используй readdir();

nerezus 06.11.2008 00:22

Базу юзай. Чтобы рекурсивно не лазить по директориям. Легче гораздо это. Да и теоретически быстрее.

Хотя для твоего проекта все равно - он не будет настолько популярным, чтобы замечать разницу.

mr.The 06.11.2008 00:38

база имхо.
к теме надо опрос прикрутить =\

nerezus 06.11.2008 01:20

не нужен опрос. Да и автор не знает походу, что ему надо.

EST a1ien 06.11.2008 11:20

nerezus что ты на меня сразу набросился?

Цитата:

Хотя для твоего проекта все равно - он не будет настолько популярным, чтобы замечать разницу.
Я не говорил нечего не про какой проет. Мне просто интересно что в данному случае лучше.
Кстати ненадо получать рекурсивно список файлов. Нужно только список из папки/подпапки.
А нагрузка будет хотябы потому что файлов в папки будет порядка 500 штук(возможно больше)
Цитата:

не нужен опрос. Да и автор не знает походу, что ему надо.
И опять ты на меня накинулся. Такое впечатление будто я тебя прошу за меня что-то писать или сделать.

ЗЫ уже двое за базу. Кстати можно еще прокешировать запрос к базе(так-как инфа меняться будет ну очень редко)

++Norton++ 06.11.2008 11:52

Тоже за базу. Должно быть быстрее.

Trieg 06.11.2008 15:47

бд полюбому будет лучшим вариантом.. 500 файлов постоянно дергать неудобно + с бд больше возможностей

Red_Red1 11.11.2008 18:38

Пока уезжал тема упала, ну да ясно что тут долго обсуждать.
Предлагаю свой вариант "что бы быстрее".

Нам в любом случае понадобиться отсканить директории что бы мы не использовали базу или файл.
Хранить дерево предлагаю в массиве такой структуры
Код:

Array
(
    [0] => file1
    [1] => file2
    [2] => file3
    [DIR1] => Array
        (
            [0] => file1
            [1] => file2
        )
    [DIR2] => Array
        (
            [0] => file1
            [1] => file2
            [2] => file3
            [SUBDIR1] => Array
                (
                  [0] => file1
                  [1] => file2
                  [2] => file3
                )
        )

Дальше мы можем сериализовать массив (serialize) и засунуть строку в файл. Потом грузить массив из файла и пользоваться им для навигации. Можно положить строку сериализованого массива в базу. Тут вопрос, база данных ведь тоже представляет собой файл(ы) получается мы будем обращаться к файлам в любом случае, так какая разница что использовать базу или файл? (очень хочу узнать ответ : )) Хотя можно в базе хранить дерево не одной записью, а несколькими, тогда смысл может и будет, выигрываем в объеме загружаемых данных.
Далее, начинаем ускорять это дело. Мысль такая использовать кеширование в памяти. Т.е. будем хранить в памяти на сервере массив дерева каталогов при необходимости берем массив сразу из памяти, а не с файла/базы.
Объем памяти потребуется относительно небольшой.
Вот примерный расчет взят с моего диска С. Общее количество файлов и папок 14000 (установлена винда ХП, офис, и несколько других программок). Возьмем среднее количество букв в имени файла/папки равным 15 (символов). Итого имеем 14000*15=210000 (байт-символов) или 205 килобайт. Много мало решать вам.
Теперь все это в коде.
1. Сканер директорий.
PHP код:

 <?php
$memcache 
= new Memcache();
$memcache->pconnect('127.0.0.1'11211);//Подключаем сервер кеша

function dir_tree($root)//Рекурсивная функция для сканирования директории. Возвращает массив-дерево
  
{
    
$res = array();$root .= '/';
    
$dirs scandir($root);
    foreach(
$dirs as $name){
      if(
is_dir($root.$name)){
        if(
$name == '.' || $name == '..'){
          continue;
        }
        
$res[$name] = dir_tree($root.$name);
      }else{
        
$res[] = $name;
      }
    }
   return 
$res;    
  }

  
$root = isset($_GET['root']) ? $_GET['root'] : '';
  
$root substr($root,0,1) == '|' substr($root,1) : $root;
  
$scan = isset($_GET['scan']);
  if(
$scan){
    
set_time_limit(0);
    
$tree=dir_tree($root);//Получаем массив-дерево
    
file_put_contents('d:/dir.txt',serialize($tree));//Сохраняем в файл полученый массив-дерево (можно не делать если не будем использовать файлы)
    
$memcache->set('all_data_m'$treefalse60000);//Сохраняем массив в кеше (если будем работать через кеш. Не забыть выставить нужное время!)
    
echo "Ok!";
   }
  
echo 
"<FORM ><INPUT type=text name = root><br />//Форма в которой укаываем диру для построение дерева.
  <input type =hidden name=scan value=1>
  <input type=submit value=scan></FORM><br />"
;
?>

2. Скрипт навигации на основе массива дерева каталогов используя кеш в памяти.
PHP код:

 <?php
$memcache 
= new Memcache();
$memcache->pconnect('127.0.0.1'11211);//Конект  к кешу
 /**
  * function array_getbranch Возвращает указанный элемент массива
  * т.е. преобразовывает строку вида dir1|dir2|...|dirN в $var[dir1][dir2]...[dirN] - массив
  * Уровни массива в строке разделяются |
  * Если данного элемента нет, то вернет NULL
  *$branch string Строка-путь к элементам
  * $arr array|null Массив для обработки, если NULL, то вернет только "строку доступа" ([a][b][c]...), а не значение
  *  c данного массива
  * @return mixed Указанный узел/"строка доступа"/NULL(если ветка с ошибками или не существует такого элемента)
  */
function array_getbranch($branch,$arr null)
 {
  if(
$branch != '' && !preg_match("/^(?:\[\'[\w\d\- ]+\'\])+$/",$branch "['".str_replace('|',"']['",$branch)."']"))
   {
    return 
null//если ветка не пустая и в ней ошибка -> результат уже ясен
   
}
  return 
is_null($arr) ? $branch : eval("return @\$arr$branch;");
 }  

// ----------- Засекаем время -{Начаало}----------------------------
$mtime microtime();
$mtime explode(" ",$mtime);
$mtime $mtime[1] + $mtime[0];
$tstart $mtime;
// ------------ Засекаем время {Конец}------------------------
  
  
$root = isset($_GET['root']) ? $_GET['root'] : '';
  
$root substr($root,0,1) == '|' substr($root,1) : $root;
  
  
$tmp $memcache->get('all_data_m');//Берем из кеша массив
  
$data array_getbranch($root,$tmp);//Получаем нужный элемент массива по параметру  $root (dir1|dir2|...|dirN)
  
  
echo "<PRE>";
  
//print_r ($data);
  
$ret substr($root,0,strrpos($root,'|'));
  echo 
'"'.str_replace('|','\\',$root)."\"<br />";
  echo 
"<br /><A href = \"?root=$ret\">..</A><br />" ;
  foreach(
$data as $key=>$value)//Выводим в браузер содержимое каталога.
   
{
    echo 
"<br />";
    if(
is_array($value)){
      echo 
"<A href=\"?root=$root|$key\">$key</A>";
    }else{
      echo 
"$value";
    }
   }

// ------- считаем пройденное время --------------Начало
$mtime microtime();
$mtime explode(" ",$mtime);
$mtime $mtime[1] + $mtime[0];
$tend $mtime;
$totaltime ceil(($tend $tstart)*10000)/10000;
$time='<br />Страница сгенерирована за '.$totaltime.' секунд.';
// ------- считаем пройденное время --------------Конец
echo $time;
?>

Первый скрипт запускаем один раз для сканирования, а вторым пользуемся для навигации. Если структура каталогов изменилась, то снова нужно запустить сканирование.
Можно сделать разные проверки и прочее, но это нужно уже для конкретной задачи.
Вот такое вот решение. Интересно услышать критику.
З.Ы.
Для использования кеша придется установить memcache. Очень коротко почитать можно тут
http://www.webnext.ru/blog/2007/09/18/php-memcache.html
Есть версия для винды (ей и пользовался)
http://jehiah.cz/projects/memcached-win32/

fucker"ok 11.11.2008 22:39

А что ты мучаешься. один тест у тебя уже сделано напиши второй и для БД =)

Я думаю что БД быстрее т.к. хранить в каждом запущенном скрипте структуру из 14к элементов - накладно.
Да и в БД есть тоже свой кеш, который можно настроить.


Время: 22:34