[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: eval в цикле
LRCenter
Использую eval() для передачи строки условий в функцию, в которой оно проверяется в цикле, применительно к большому массиву, вот так:

if(eval("return $ustr;")){...}

Проблема в том что c eval-ом все это хозяйство работает почти в два раза медленне чем указание условий прямо в коде функции. От eval-а отказаться не могу - не вижу альтернативы, долго объяснять.

Может быть можно как-нибудь вынести eval за пределы цикла? Но как тогда заставить строку условия работать как код?



Спустя 1 час, 1 минута, 58 секунд (4.05.2011 - 21:36) sergeiss написал(а):
Цитата (LRCenter @ 4.05.2011 - 21:34)
От eval-а отказаться не могу - не вижу альтернативы, долго объяснять.

Лучше потрать время на объяснение. Вместе подумаем, как сделать побыстрее.

Спустя 13 часов, 28 минут, 57 секунд (5.05.2011 - 11:05) LRCenter написал(а):
Хорошо, давайте подумаем как можно оптимизировать это.

function fCSVgetstr($db, $ustr = NULL, $cutnum = NULL, $scol = NULL, $rev = NULL) {
if (file_exists($db)) {
if ($cutnum != "") {
$cutnum = explode(",", $cutnum);
}
if ($ustr == "") {
$ustr = "1==1";
} else {
$ustr = str_replace("CELL[", "\$strar[", $ustr);
}
$exarr = array();
if ($scol == "") {
$scol = 1;
}
if ($scol == "all") {
$rev = "";
}
$handler = fopen($db, 'r');
$conuter = 0;
while (!feof($handler)) {
$str = fgets($handler);
$strar = explode(";", $str);
if (eval("return $ustr;")) {
if ($cutnum != "") {
$str = "";
foreach($cutnum as $cellnm) {
$str.= $strar[$cellnm] . ";";
}
$str = trim($str, ";");
}
$exarr[] = $str;
++
$conuter;
if ($rev == 1) {
if ($conuter > $scol) {
$varr = array_shift($exarr);
}
}
else {
if ($scol != all) {
if ($scol <= $conuter) {
break;
}
}
}
}
}

fclose($handler);
if (count($exarr) != 0) {
return $exarr;
} else {
return FALSE;
}
}
else {
return FALSE;
}
}



Итак, это функция получения строк, исходя из условий (возвращает массив строк с ключем с нуля)

-Параметры:
1. База(путь до csv-таблицы),
2. Выражение условия(нумерация ячеек(Шаблон)- CELL[x] с 0),
3. Оставить только ячейки(список номеров через ",", с 0, по умолчанию - все),
4. [захватить количество строк - по умолчанию 1, "all"-все],
5. Флаг реверса указателя - [(1)с конца, (0) по умолчанию - с начала]

Прмер использования.
print_r(fCSVgetstr("test2.csv", "CELL[0] == '1297941442-c4e8987t18' && CELL[4] != ''", "0,2,3", 10, 1));


В принципе показывает довольно неплохие результаты. Например в базе с ~11000 статей(>11к строк, 12 столбцов), около 150Мб, сложная выборка по пяти параметрам выполняется < чем за 0,3 сек.

Если прописать выражение условия вручную, прямо в функцию, т.е. не использовать eval() выполняется в серднем за 0,16-17сек. т.е. почти в 2 раза быстрее. Все цифры получены на обычном виртуальном хостинге.

Есть резон оптимизировать, но как? Необходимо сохранить возможность передавать произвольное условие в функцию, чтобы не переписывать ее каждый раз.

Спустя 20 минут, 27 секунд (5.05.2011 - 11:26) linker написал(а):
Интересен вообще принцип
if (eval("return $ustr;")) { }
return прерывает выполнение функции и возвращает результат (или не возвращает).
eval("return $ustr;")
должен выполниться в контексте текущей функции, а значит fCSVgetstr()завершит свою работу в момент выполнения этого eval'а, потому какие тут могут быть вообще if () {}это
if (eval("return $ustr;")) { }
равносильно этому
if (return $ustr)) { }
но это полный бред.

Спустя 4 минуты, 17 секунд (5.05.2011 - 11:30) LRCenter написал(а):
linker
Знаешь, чувак, - это работает)))
Проверь. biggrin.gif

Спустя 10 минут, 28 секунд (5.05.2011 - 11:40) LRCenter написал(а):
Цитата
return прерывает выполнение функции и возвращает результат


Вероятно содержимое eval() обрабатывается в одельной области памяти, а потому return внутри eval-а не пересекается с return-ом внешенй функции, это как вложенные функции.

eval не возвращает return, ведь это указаение для eval-а, или я не прав?

Спустя 23 минуты, 49 секунд (5.05.2011 - 12:04) sergeiss написал(а):
Цитата (LRCenter @ 5.05.2011 - 12:40)
eval не возвращает return, ведь это указаение для eval-а, или я не прав?

Да, ты не прав. Потому что eval выполняет то, что ему передано. В данном случае выполняется return из функции, в результате чего твой ИФ совершенно не нужен. Об этом линкер тебе и говорил.

Спустя 1 минута, 46 секунд (5.05.2011 - 12:06) LRCenter написал(а):
Не понял. Обясните.

Спустя 1 минута, 59 секунд (5.05.2011 - 12:08) LRCenter написал(а):
Почему тогда условие работает, и нужное количество раз? Почему функция не прерывается сразу при первом прохождении цикла, как говорит Линкер?

Спустя 16 минут, 25 секунд (5.05.2011 - 12:24) linker написал(а):
Млин, въехал, мануал рулит. Почитай мануал на счет eval(), поймёшь.

Спустя 4 минуты, 46 секунд (5.05.2011 - 12:29) LRCenter написал(а):
linker
Блин, объясни! Пока врубаться буду состарюсь и умру smile.gif

Спустя 6 минут, 25 секунд (5.05.2011 - 12:35) linker написал(а):
Если внутри выражения есть return, то eval() вернет значение выполненного выражения. Млин, пример лучше покажет суть.
function a()
{
$a = 1;
$b = eval('return ++ $a;');
echo $a . ' - ' . $b;
}

a();
На выходе будет
2 - 2
Т.е. return внутри eval() работает как немедленный возврат из функции eval(), в противном случае eval() вернет FALSE. Уфф, млин, жесть.

Спустя 2 минуты, 40 секунд (5.05.2011 - 12:38) LRCenter написал(а):
Понятно, я так и подумал. Кстати без return ниче не работало, потому я его и добавил - интуитивный кодинг блин)))

Но основной вопрос остается открытым. Что тут можно оптимизировать с сохранением функционала?

Спустя 1 час, 20 минут, 6 секунд (5.05.2011 - 13:58) LRCenter написал(а):
Я истолковываю молчание гуру php как то что оптимизация в данном случае невозможна.

Спустя 11 минут, 44 секунды (5.05.2011 - 14:10) linker написал(а):
Чтобы разобрать сей чудный код, нужно потратить немалое время, а времени у нас нет пока.

Спустя 33 минуты, 31 секунда (5.05.2011 - 14:43) LRCenter написал(а):
Тогда я терпеливо подожду пока время появится.


_____________
Меньше кода - меньше багов ©
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.