Правила     Закладки     Карма    Календарь    Журналы    Помощь    Поиск    PDA    Чат   
        СМС-ки
   
Пейджер выключен!
Страницы: (2) [1] 2  ( Перейти к первому непрочитанному сообщению )  
Фильтр авторов:    показать 
  скрыть
  Ответ в темуСоздание новой темыСоздание опроса

> eval(), не колхоз ли делать такую конструкцию?
GET  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



TERRAFORMING ENGINEER
******

Профиль
Журнал
Группа: ★ЛжеЭксперт★
Завсегдатай форума
Сообщений: 3890
Пользователь №: 21196
На форуме: 7 лет, 2 месяца, 21 день
Карма: 87




Привет.

Задача такая: динамически объединять двумерные массивы с целью получения одномерного. Остановился на использовании array_merge, но наткнулся на статью (http://p2k.ru/archives/44), где по результатам тестов не рекомендуется многократно активировать array_merge, а советуют сначала сделать набор из массивов, а потом запихнуть его в array_merge при помощи eval().

Примерно вот так. Сделал вроде работает, вроде быстрее. Но как-то не по программистки что-ли... Что думаете?



$str[1][]=1;
$str[1][]=2;
$str[1][]=3;

$str[2][]=4;
$str[2][]=5;

$str2=array();

foreach($str as $i=>$val)$str2[]='$str['.$i.']';
eval('$str3=array_merge('.implode(',',$str2).');');
foreach($str3 as $val)echo$val;


--------------------
Не тот велик, кто не падал, а тот кто падал и поднимался.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
xlebosol  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Знатный быдлокодер
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 337
Пользователь №: 32761
На форуме: 4 года, 11 месяцев, 4 дня
Карма: 19




"PHP5" Леон Аткинсон, Зеев Сураски 2006 - Избегайте использования функции eval.

Перед тем как углубиться в детали, запомните, что "eval() - это зло". ......
PMПисьмо на e-mail пользователюICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
andrey888  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 793
Пользователь №: 27801
На форуме: 6 лет, 14 дней
Карма: 14




eval() == evil )


--------------------
Прогноз на следующие 5 лет : Россия, Китай - две величайшие державы.
США в Ж*пе. Справедливость восторжествует. )
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
GET  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



TERRAFORMING ENGINEER
******

Профиль
Журнал
Группа: ★ЛжеЭксперт★
Завсегдатай форума
Сообщений: 3890
Пользователь №: 21196
На форуме: 7 лет, 2 месяца, 21 день
Карма: 87




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


--------------------
Не тот велик, кто не падал, а тот кто падал и поднимался.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
xlebosol  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Знатный быдлокодер
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 337
Пользователь №: 32761
На форуме: 4 года, 11 месяцев, 4 дня
Карма: 19




Вместо eval(), лучше применить анонимную функцию.
PMПисьмо на e-mail пользователюICQ
    1   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
GET  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



TERRAFORMING ENGINEER
******

Профиль
Журнал
Группа: ★ЛжеЭксперт★
Завсегдатай форума
Сообщений: 3890
Пользователь №: 21196
На форуме: 7 лет, 2 месяца, 21 день
Карма: 87




xlebosol
Гм ... Интересная идея, как то их не использовал ни разу


--------------------
Не тот велик, кто не падал, а тот кто падал и поднимался.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
GET  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



TERRAFORMING ENGINEER
******

Профиль
Журнал
Группа: ★ЛжеЭксперт★
Завсегдатай форума
Сообщений: 3890
Пользователь №: 21196
На форуме: 7 лет, 2 месяца, 21 день
Карма: 87




xlebosol
Нет не подойдет....это все равно вызовет многократное использование array_merge.


--------------------
Не тот велик, кто не падал, а тот кто падал и поднимался.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
glock18  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Be prepared
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 5199
Пользователь №: 17723
На форуме: 8 лет, 11 дней
Карма: 57




eval = зло, но анонимку тут не применить насколько я вижу, поскольку кол-во массивов переменно.

ABC
смотрите сами на то, как это отражается на быстродействии.

Для сравнения было бы неплохо видеть и второй ваш вариант решения без eval. Как бы то ни было, если плохой eval оказывается здесь заметно быстрее необруганного array_merge (а быстродействие - то что всегда ставится в минус eval'у), то, очевидно, ругают не то.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
xlebosol  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Знатный быдлокодер
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 337
Пользователь №: 32761
На форуме: 4 года, 11 месяцев, 4 дня
Карма: 19




Тогда добро пожаловать в неизведанный мир итераторов (iteratorIterator, ArrayIterator) и т.д.. Что то array_merge не то мержит, в данном случае и без эвалов и array_merge можно обойтись.
PMПисьмо на e-mail пользователюICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
kaww  
[x] Дата
Цитировать сообщение

Пользователь сейчас на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1784
Пользователь №: 20757
На форуме: 7 лет, 3 месяца, 21 день
Карма: 186




Вот по тестил. Все же eval немного быстрее (не значительно, так что можно пренебречь). За то второй вариант красивее )
function genArray($a = 10, $b = 10)
{
$result = array();
for ($i = 0; $i < $a; ++$i) {

$result[] = array_fill(0, $b, hash('adler32', rand(0, 99)));
}
return $result;
}

$array = genArray(500, 500);

//eval
$start = microtime(true);
$str2 = array();
foreach ($array as $i => $val) $str2[] = '$array[' . $i . ']';
eval('$str3=array_merge(' . implode(',', $str2) . ');');
var_dump(microtime(true) - $start);

//reflection
$start = microtime(true);
$reflection = new ReflectionFunction('array_merge');
$result = $reflection->invokeArgs($array);
var_dump(microtime(true) - $start);


результат

Цитата
float 0.081470966339111
float 0.087764024734497
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
GET  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



TERRAFORMING ENGINEER
******

Профиль
Журнал
Группа: ★ЛжеЭксперт★
Завсегдатай форума
Сообщений: 3890
Пользователь №: 21196
На форуме: 7 лет, 2 месяца, 21 день
Карма: 87




Цитата
Остановился на использовании array_merge


Цитата
Справедливости ради стоит отметить, что во втором тесте array_merge не используется вовсе. По этому если для решения задачи не принципиальна разница между array_merge(arr1, arr2) и arr1 + arr2, то лучше выбрать второй вариант.


+ За проделанную работу, но разница важна.

$str[1][]=1;
$str[1][]=2;
$str[1][]=3;

$str[2][]=4;
$str[2][]=5;

//....
//$str[N]=N1;
//$str[N]=N2;


$str2=array();
foreach($str as $i=>$val)
{
$str2=array_merge($str2,$val);//Результат:1,2,3,4,5
//$str2=$str2+$val;//Результат:1,2,3

}
foreach($str2 as $val)echo $val;


Вот здесь исходник статьи о которой я упомянул в начале поста, там результаты тестов:
http://p2k.ru/archives/44

Может я устал уже за день и туго соображаю. Мне не понятно, как тут можно обойтись без этого:

Я же объясняю использовать для сложения не затерев ключи можно только:array_merge

Многократное использование array_merge тяжелее однократного. Для однократного нужно динамически перечислить массивы сделать это можно тогда когда array_merge вместе с аргументами будет просто строкой, а eval выполнит эту команду со стороны.


--------------------
Не тот велик, кто не падал, а тот кто падал и поднимался.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
kaww  
Дата
Цитировать сообщение

Пользователь сейчас на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1784
Пользователь №: 20757
На форуме: 7 лет, 3 месяца, 21 день
Карма: 186




ABC
, тот пост я удалил, по тому что код оказался не совсем рабочим, а точнее совсем не рабочим ;) .

Цитата
Многократное использование array_merge тяжелее однократного. Для однократного нужно динамически перечислить массивы сделать это можно тогда когда array_merge вместе с аргументами будет просто строкой, а eval выполнит эту команду со стороны.


постом выше предложил вариант с reflection

$reflection = new ReflectionFunction('array_merge');
$result = $reflection->invokeArgs($array);
PMПисьмо на e-mail пользователю
    1   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
GET  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



TERRAFORMING ENGINEER
******

Профиль
Журнал
Группа: ★ЛжеЭксперт★
Завсегдатай форума
Сообщений: 3890
Пользователь №: 21196
На форуме: 7 лет, 2 месяца, 21 день
Карма: 87




kaww
Разве у тебя не применяется многократная инициализация array_merge? Все просто внутри класса происходит. Так ведь?

Я не спорю, но в той статье ключевым помоему является вот эта правильная мысль:
Цитата
Получилось вот что: в функции array_merge самый долгий процесс - ее инициализация, потому в цикле она очень медленная. Но… если применить слияние большого числа массивов одним вызовом, то равных этой функции не станет.


--------------------
Не тот велик, кто не падал, а тот кто падал и поднимался.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
xlebosol  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Знатный быдлокодер
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 337
Пользователь №: 32761
На форуме: 4 года, 11 месяцев, 4 дня
Карма: 19




<?php
$str[1][]=1;
$str[1][]=2;
$str[1][]=3;

$str[2][]=4;
$str[2][]=5;

$str2=array();

foreach($str as $i=>$val) {
$str2[] = $str[$i];
}

$it = new RecursiveIteratorIterator( new RecursiveArrayIterator($str2));

foreach ($it as $key=>$val)
echo $val."\n";
?>
PMПисьмо на e-mail пользователюICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
kaww  
Дата
Цитировать сообщение

Пользователь сейчас на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1784
Пользователь №: 20757
На форуме: 7 лет, 3 месяца, 21 день
Карма: 186




ABC
Как это происходит нужно спросить у разработчиков пхп http://www.php.net/manual/ru/class.reflectionfunction.php
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
  Быстрый ответ
Информация о Госте
Введите Ваше имя
Кнопки кодов
Для вставки цитаты, выделите нужный текст и
НАЖМИТЕ СЮДА
Введите сообщение
Смайлики
:huh:  :o  ;) 
:P  :D  :lol: 
B)  :rolleyes:  <_< 
:)  :angry:  :( 
:unsure:  :blink:  :ph34r: 
     
Показать всё

Опции сообщения  Включить смайлики?
 Включить подпись?
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:

Опции темыСтраницы: (2) [1] 2  Ответ в темуСоздание новой темыСоздание опроса