ФорумПрограммированиеPHP для идиотов → Задачка на микрооптимизацию, чтобы не скучали

Задачка на микрооптимизацию, чтобы не скучали

  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 17 февраля 2012 г. 3:12

    Есть правило преобразования URL в имя класса с неймспейсами и обратно. Типа:

    /alfa/beta-gamma/sigma
    \Alfa\BetaGamma\Sigma


    Кто напишет самый эффективный по времени код, тот молодец.
    Мой собственный вариант с таймером:

    <?php

    class Router
    {
    static function pathToClass($s)
    {
    return implode('\\', array_map(array('self', 'hyphenToCamel'), explode('/', $s)));
    }

    static function classToPath($s)
    {
    return implode('/', array_map(array('self', 'camelToHyphen'), explode('\\', $s)));
    }

    private static
    $S = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'),
    $R = array('-a','-b','-c','-d','-e','-f','-g','-h','-i','-j','-k','-l','-m',
    '-n','-o','-p','-q','-r','-s','-t','-u','-v','-w','-x','-y','-z');

    private static function hyphenToCamel($item)
    {
    return implode('', array_map('ucfirst', explode('-', $item)));
    // return ucfirst(str_replace(self::$R, self::$S, $item));
    }

    private static function camelToHyphen($item)
    {
    return trim(str_replace(self::$S, self::$R, $item), '-');
    }
    }

    $a = '/alfa/beta-gamma/sigma';

    $t1 = microtime(TRUE);
    for ($i=1; $i<1000; ++$i)
    $b = Router::pathToClass($a);
    $t1 = microtime(TRUE) - $t1;

    $t2 = microtime(TRUE);
    for ($i=1; $i<1000; ++$i)
    $c = Router::classToPath($b);
    $t2 = microtime(TRUE) - $t2;

    echo $a . "<br/>\n"
    . $b . "<br/>\n"
    . sprintf('%.6f', $t1) . "<br/>\n"
    . $c . "<br/>\n"
    . sprintf('%.6f', $t2) . "<br/>\n";

    На моей машинке результат
    0.029087 и 0.070009
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 17 февраля 2012 г. 4:14, спустя 1 час 2 минуты 6 секунд

    ОМГ
    Сапожник без сапог
  • Frozzeg

    Сообщения: 5641 Репутация: N Группа: Джедаи

    Spritz 17 февраля 2012 г. 4:53, спустя 39 минут 43 секунды

    твой вариант 0.026678 и 0.052827

    мой 0.015249 и 0.043921

    class Router
    {
    static function pathToClass($s)
    {
    $splitted_path = explode("/", $s);
    $result = "";

    foreach( $splitted_path as $part )
    {
    if( $part != "" )
    {
    $part_links = explode( "-", $part );
    $temp_result = "";

    foreach( $part_links as $link )
    {
    $temp_result .= ucfirst( $link );
    }

    $local_res = ucfirst( $temp_result );

    $result .= "\\".$local_res;
    }
    }
    return $result;
    }

    static function classToPath($s)
    {
    $splitted_path = explode("\\", $s);
    $result = "";

    foreach( $splitted_path as $part )
    {
    if( $part != "" )
    {
    $uppercase_counter = 0;
    $temp_result = "";

    for( $i = 0; $i < strlen( $part ); $i ++ )
    {
    if( $part[$i] === strtoupper( $part[$i] ))
    $uppercase_counter ++;

    if( $uppercase_counter > 1 )
    {
    $temp_result .= "-".$part[$i];
    $uppercase_counter –;
    }
    else $temp_result .= $part[$i];
    }
    $result .= "/".$temp_result;
    }
    }
    return strtolower( $result );
    }
    }
    You can be anything you want to be. Just turn yourself into anything you think that you could ever be.
  • technobulka

    Сообщения: 4540 Репутация: N Группа: Джедаи

    Spritz 17 февраля 2012 г. 5:16, спустя 22 минуты 45 секунд

    а я на пехепе не умею))

    str = '/alfa/beta-gamma/sigma'
    .replace(/(\/|-)(\w)/g, function(a,b,c) {
    return (b == '-' ? '' : '\\') + c.toUpperCase()
    })
    console.log(str) // \Alfa\BetaGamma\Sigma

    str = '\\Alfa\\BetaGamma\\Sigma'
    .replace(/(\\|\w)([A-Z])/g, function(a,b,c) {
    return (b == '\\' ? '/' : b + '-') + c.toLowerCase()
    })
    console.log(str) // /alfa/beta-gamma/sigma
    Высокоуровневое абстрактное говно
  • Ivan

    Сообщения: 1316 Репутация: N Группа: Адекваты

    Spritz 17 февраля 2012 г. 5:27, спустя 11 минут 10 секунд

    По моему это очень не безопасно так делать
  • Nyaah

    Сообщения: 574 Репутация: N Группа: Джедаи

    Spritz 17 февраля 2012 г. 5:34, спустя 6 минут 12 секунд

    Чего небезопасно то? Боишься что у тебя вместо класса контроллера класс какой-нить \my\super\mega\mvc\router вызовут, или несуществующий класс? ))
    Обычно же эта фигня вызывается в контексте эппликейшена в виде $this->setController(new $controller), причем setController(IController $controller), в итоге если был вызван какой-нить левый класс, то просто движок посрёт в логи да и все, либо юзверь увидит страницу, что нельзя кастовать тратата класс в IController.
    Work, buy, consume, die
  • Ivan

    Сообщения: 1316 Репутация: N Группа: Адекваты

    Spritz 17 февраля 2012 г. 5:35, спустя 1 минуту 54 секунды

    Обычно же эта фигня вызывается в контексте эппликейшена в виде $this->setController(new $controller), причем setController(IController $controller), в итоге если был вызван какой-нить левый класс, то просто движок посрёт в логи да и все, либо юзверь увидит страницу, что нельзя кастовать тратата класс в IController.

    Не, ну это то понятно
  • Frozzeg

    Сообщения: 5641 Репутация: N Группа: Джедаи

    Spritz 17 февраля 2012 г. 7:10, спустя 1 час 34 минуты 55 секунд

    0.014181 и 0.037781

    class Router
    {
    static function pathToClass($s)
    {
    $splitted_path = explode("/", $s);
    $result = "";

    unset( $splitted_path[0] );
    foreach( $splitted_path as $part )
    {
    $part_links = explode( "-", $part );
    $temp_result = "";

    foreach( $part_links as $link )
    {
    $temp_result .= ucfirst( $link );
    }

    $local_res = ucfirst( $temp_result );

    $result .= "\\".$local_res;
    }
    return $result;
    }

    static function classToPath($s)
    {
    $splitted_path = explode("\\", $s);
    $result = "";

    unset( $splitted_path[0] );
    foreach( $splitted_path as $part )
    {
    $uppercase_counter = 0;
    $temp_result = "";
    $part_length = strlen( $part );

    for( $i = 0; $i < $part_length; $i ++ )
    {
    if( $part[$i] == strtoupper( $part[$i] ))
    $uppercase_counter ++;

    if( $uppercase_counter > 1 )
    {
    $temp_result .= "-".$part[$i];
    $uppercase_counter –;
    }
    else $temp_result .= $part[$i];
    }
    $result .= "/".$temp_result;
    }
    return strtolower( $result );
    }
    }
    You can be anything you want to be. Just turn yourself into anything you think that you could ever be.
  • Ivan

    Сообщения: 1316 Репутация: N Группа: Адекваты

    Spritz 17 февраля 2012 г. 7:15, спустя 4 минуты 14 секунд

    $this->setController(new $controller)

    бабах - и вызвался конструктор, и даже если php подавится эксепшеном - факта того, что конструктор выполнится, ты, не избежал
  • Nyaah

    Сообщения: 574 Репутация: N Группа: Джедаи

    Spritz 17 февраля 2012 г. 8:38, спустя 1 час 23 минуты 1 секунду


    $this->setController(new $controller)

    бабах - и вызвался конструктор, и даже если php подавится эксепшеном - факта того, что конструктор выполнится, ты, не избежал
    Не поверишь, но конструктор создан для того чтобы инициилизировать объект, если у тебя в конструктор запихана какая-то логика, изменяющая окружение, то ты сам себе деревянный буратино.
    Если совсем уже невмоготу, то проверяй вручную перед созданием иерархию наследования или валидность типа.
    Work, buy, consume, die
  • kostyl

    Сообщения: 5210 Репутация: N Группа: Джедаи

    Spritz 17 февраля 2012 г. 8:51, спустя 12 минут 57 секунд

    Не хочу проверять, потому что это быстрее всех ))

    function callback($matches) {
    if (isset($matches[0]) && (strlen($matches[0]) === 2) && isset($matches[0][0]) && isset($matches[0][1])) {
    return ($matches[0][0] == '-') ? strtoupper($matches[0][1]) : '\\' . strtoupper($matches[0][1]);
    }
    }
    echo preg_replace_callback('![/-]+(.)!iu', 'callback', $url);
  • Ivan

    Сообщения: 1316 Репутация: N Группа: Адекваты

    Spritz 17 февраля 2012 г. 9:21, спустя 30 минут 16 секунд



    $this->setController(new $controller)

    бабах - и вызвался конструктор, и даже если php подавится эксепшеном - факта того, что конструктор выполнится, ты, не избежал
    Не поверишь, но конструктор создан для того чтобы инициилизировать объект, если у тебя в конструктор запихана какая-то логика, изменяющая окружение, то ты сам себе деревянный буратино.
    Если совсем уже невмоготу, то проверяй вручную перед созданием иерархию наследования или валидность типа.


    Могут быть такие модули в PEAR или самом PHP, которые при конструкторе могут что-то сделать, и виноват тут уже будет не буратино. Так что не убедил
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 18 февраля 2012 г. 23:48, спустя 1 день 14 часов 27 минут

    Ivan, во первых я никого не уговариваю делать так, тред не об этом.
    во вторых, достаточно перед созданием объекта добавить свой префикс - корневой неймспейс чтобы гарантировать, что будет использован класс из допустимого подмножества. $class = '\MyController' . Router::pathToClass($uri);

    p.s. Пропустил комментарий Nyaah, он правильно пишет — достаточно иметь указание на принадлежность класса к нужному интерфейсу. Всё это выходит за рамки нашей задачи.

    сейчас разберу ваши варианты… вы лохи, это уже понятно… щас…
    ιιlllιlllι унц-унц
  • Troy

    Сообщения: 2532 Репутация: N Группа: Джедаи

    Spritz 18 февраля 2012 г. 2:07, спустя 2 часа 18 минут 53 секунды

    Интересная тема. Предлагаю чаще устраивать такие соревнования.
  • kostyl

    Сообщения: 5210 Репутация: N Группа: Джедаи

    Spritz 18 февраля 2012 г. 2:26, спустя 19 минут 6 секунд

    сейчас разберу ваши варианты… вы лохи, это уже понятно… щас…

    Ну чё, разобрал мой вариант?

Пожалуйста, авторизуйтесь, чтобы написать комментарий!