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

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

  • artoodetoo

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

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

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

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


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

    <?php

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

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

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

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

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

    $a = &#39;/alfa/beta-gamma/sigma&#39;;

    $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 . &quot;<br/>\n&quot;
    . $b . &quot;<br/>\n&quot;
    . sprintf(&#39;%.6f&#39;, $t1) . &quot;<br/>\n&quot;
    . $c . &quot;<br/>\n&quot;
    . sprintf(&#39;%.6f&#39;, $t2) . &quot;<br/>\n&quot;;

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

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

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

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

    Сообщения: 5642 Репутация: 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(&quot;/&quot;, $s);
    $result = &quot;&quot;;

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

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

    $local_res = ucfirst( $temp_result );

    $result .= &quot;\\&quot;.$local_res;
    }
    }
    return $result;
    }

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

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

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

    if( $uppercase_counter > 1 )
    {
    $temp_result .= &quot;-&quot;.$part[$i];
    $uppercase_counter –;
    }
    else $temp_result .= $part[$i];
    }
    $result .= &quot;/&quot;.$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

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

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

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

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

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

    Сообщения: ? Репутация: 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

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

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

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

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

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

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

    0.014181 и 0.037781

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

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

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

    $local_res = ucfirst( $temp_result );

    $result .= &quot;\\&quot;.$local_res;
    }
    return $result;
    }

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

    unset( $splitted_path[0] );
    foreach( $splitted_path as $part )
    {
    $uppercase_counter = 0;
    $temp_result = &quot;&quot;;
    $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 .= &quot;-&quot;.$part[$i];
    $uppercase_counter –;
    }
    else $temp_result .= $part[$i];
    }
    $result .= &quot;/&quot;.$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

    Сообщения: ? Репутация: 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

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

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

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

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

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

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



    $this->setController(new $controller)

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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