ついでに絶対URLの取得ベンチマーク

スクレイピングにほとんど必須な作業に、相対パスからhttp://〜のURLを導きだす作業があるわけですが、Diggin_ScraperのデフォのアダプターにしているHTMLScraping classなんかは、正規表現+pearのNet/URLを組み合わせた関数(getAbsoluteUrl)が用意されてまして、それでももちろんOKというか、ピュアPHPなのでそれでいいじゃんていう訳ですが、pecl_httpを使うと正規表現やる必要がないんですよね。やったー。ほら、PHPって正規表現組み込みじゃないから使いにくいし〜


前々から気になっていたので、ベンチマーク。ただし、私が作ったhttp_build_url仕様のやつは、全部のパターン網羅できてないかも。
絶対URLを取得する方法は、下記のコード以外に、Rinza_IEパッケージのものとか、あるわけですが今回は除外。

<?php
require_once 'Benchmark/Iterate.php';
$bench = new Benchmark_Iterate();
error_reporting('E_FATAL');// E_STRICTでまくり
class Url
{
    
    /**
     * This is a part of HTMLScraping class
     * http://www.rcdtokyo.com/etc/htmlscraping/
     */
    public static function getAbsoluteUrlA($url, $base_url)
    {
        if (preg_match('/^[\w\+\-\.]+:/', $url) or false === $bases = @parse_url($base_url)) {
            return $url;
        } elseif (0 === strpos($url, '/')) {
            return "$bases[scheme]://$bases[host]".(isset($bases['port'])? ":$bases[port]": '').$url;
        } else {
            if (!isset($bases['path'])) {
                $bases['path'] = '/';
            }
            require_once 'Net/URL.php';
            return "$bases[scheme]://$bases[host]".(isset($bases['port'])? ":$bases[port]": '').
                Net_URL::resolvePath(substr($bases['path'], 0, strrpos($bases['path'], '/') +1).$url);
        }
    }

    public static function getAbsoluteUrlB($url, $base_url)
    {
        $parse = parse_url($url);
        if (isset($parse["host"])) {
            $build = $url;
        } else {
            $uridir = pathinfo(parse_url($base_url, PHP_URL_PATH), PATHINFO_DIRNAME);
            $slash = strpos($uridir, '/');
            if ($slash === false) {
                $build = http_build_url($base_url, array("path" => $url,),
                HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT);
            } else {            
                $build = http_build_url($base_url, array("path" => $url,), 
                HTTP_URL_JOIN_PATH | HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT);
            }
        }
        
        return $build;
    }

    public static function getAbsoluteUrlB2($url, $base_url)
    {
        static $base_url;
        if(array_key_exists('host', parse_url($url))) {
            return $url;
        } else {
            if (strpos(pathinfo(parse_url($base_url, PHP_URL_PATH), PATHINFO_DIRNAME), '/') === false) {
                return http_build_url($base_url, array("path" => $url,),
                HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT);
            } else {            
                return http_build_url($base_url, array("path" => $url,), 
                HTTP_URL_JOIN_PATH | HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT);
            }
        }
    }

}

$hrefs = array('/test.do?foo=bar', '../test.html', 'http://hoge.org/sample.php');

echo "--------getAbsoluteUrlA--------";echo PHP_EOL;
foreach ($hrefs as $href) {
//    echo Url::getAbsoluteUrlA($href, 'http://hoge.org/foo/baa/here.do'); echo PHP_EOL;
    $bench->run(100, 'Url::getAbsoluteUrlA', $href, 'http://hoge.org/foo/baa/here.do');
    $result = $bench->get();
    var_dump($result['mean']);
}

echo "--------getAbsoluteUrlB--------";echo PHP_EOL;
foreach ($hrefs as $href) {
//    echo Url::getAbsoluteUrlB($href, 'http://hoge.org/foo/baa/here.do');echo PHP_EOL;
    $bench->run(100, 'Url::getAbsoluteUrlB', $href, 'http://hoge.org/foo/baa/here.do');
    $result = $bench->get();
    var_dump($result['mean']);
}
echo "--------getAbsoluteUrlB2-------";echo PHP_EOL;
foreach ($hrefs as $href) {
//    echo Url::getAbsoluteUrlB2($href, 'http://hoge.org/foo/baa/here.do');echo PHP_EOL;
    $bench->run(100, 'Url::getAbsoluteUrlB2', $href, 'http://hoge.org/foo/baa/here.do');
    $result = $bench->get();
    var_dump($result['mean']);
}


結果

--------getAbsoluteUrlA--------
string(8) "0.000046"
string(8) "0.001838"
string(8) "0.000035"
--------getAbsoluteUrlB--------
string(8) "0.000079"
string(8) "0.000057"
string(8) "0.000042"
--------getAbsoluteUrlB2-------
string(8) "0.000047"
string(8) "0.000044"
string(8) "0.000046"
PHP 5.2.4 (cli) (built: Aug 30 2007 07:06:31)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
    with Zend Debugger v5.2.3, Copyright (c) 1999-2006, by Zend Technologies

PHP5.3で動かないーーpear.phpのせいかBenchmark_Iterateのせいかは知らない