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 написал(а):
Хорошо, давайте подумаем как можно оптимизировать это.
Итак, это функция получения строк, исходя из условий (возвращает массив строк с ключем с нуля)
-Параметры:
1. База(путь до csv-таблицы),
2. Выражение условия(нумерация ячеек(Шаблон)- CELL[x] с 0),
3. Оставить только ячейки(список номеров через ",", с 0, по умолчанию - все),
4. [захватить количество строк - по умолчанию 1, "all"-все],
5. Флаг реверса указателя - [(1)с конца, (0) по умолчанию - с начала]
Прмер использования.
В принципе показывает довольно неплохие результаты. Например в базе с ~11000 статей(>11к строк, 12 столбцов), около 150Мб, сложная выборка по пяти параметрам выполняется < чем за 0,3 сек.
Если прописать выражение условия вручную, прямо в функцию, т.е. не использовать eval() выполняется в серднем за 0,16-17сек. т.е. почти в 2 раза быстрее. Все цифры получены на обычном виртуальном хостинге.
Есть резон оптимизировать, но как? Необходимо сохранить возможность передавать произвольное условие в функцию, чтобы не переписывать ее каждый раз.
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
Знаешь, чувак, - это работает)))
Проверь.
Знаешь, чувак, - это работает)))
Проверь.
Спустя 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
Блин, объясни! Пока врубаться буду состарюсь и умру
Блин, объясни! Пока врубаться буду состарюсь и умру
Спустя 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 написал(а):
Тогда я терпеливо подожду пока время появится.
_____________
Меньше кода - меньше багов ©