【问题标题】:Filter_var's performancefilter_var 的表现
【发布时间】:2014-04-29 03:33:34
【问题描述】:

我读到filter_var 内部没有使用正则表达式。这是否意味着它比preg_match 快很多?

我想在考虑速度性能的情况下检查电子邮件验证。

编辑

这不是重复的:我不是在问区别(至于 filter_var 和 preg_match 的优点是什么),而是执行起来更快(有或没有缓存)。此外,在 cmets 中,它表明 filter_var 使用正则表达式,就像 preg_match 一样,并且在相关问题中完全忽略了此信息。

【问题讨论】:

  • 您是否尝试过对两者进行比较?
  • @AlexandruG.:不是重复的,因为另一个问题是关于差异的。它根本没有谈论速度。
  • 这在哪一方面是重复的?是因为它包含单词 filter_var 和 preg_match 吗?
  • @AmalMurali 每个推论的区别就是这个问题的答案。如果 filter_var 在内部没有使用正则表达式,则意味着更快。 “多快”是操作者应该首先发布一些自己做的测试的问题。
  • @AlexandruG.:不是真的。 filter_var() 确实在内部使用了正则表达式。见源码:github.com/php/php-src/blob/master/ext/filter/…

标签: php regex filter


【解决方案1】:

从快速基准测试来看,filter_var() 函数似乎快:

$times = 10000;

$result = array();

// preg_match version
// regex from https://github.com/php/php-src/blob/master/ext/filter/logical_filters.c#L525
$regexp = "/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD";

$email = 'foo@bar.com';

$start_m = microtime();
$start = time();
for ($i=0; $i < $times; $i++){
      preg_match($regexp, $email);
}   

$end_m = microtime();
$end = time();
$bench = ($end - $start) + ($end_m - $start_m);
$result["preg_match"] = $bench;


// filter_var version
$start_m = microtime();
$start = time();
for ($i=0; $i < $times; $i++){
      filter_var($email, FILTER_VALIDATE_EMAIL);
}

$end_m = microtime();
$end = time();
$bench = ($end - $start) + ($end_m - $start_m);
$result["filter_var"] = $bench;

print_r(
    array(
      "times" => $times,
      "results" => $result
    )
);

this gist的代码稍作修改版)

我的系统上的结果:

PHP 5.5.9-1+sury.org~saucy+1 (cli) (built: Feb 13 2014 16:01:20) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies

Array
(
    [times] => 10000
    [results] => Array
        (
            [preg_match] => 0.16649
            [filter_var] => 0.110912
        )

)

【讨论】:

  • Zend OPCache 对 filter_var 和/或 preg_match 的性能有影响吗? (我赞成你的回答)
  • Zend OpCache 优化可能会影响这两种方法;并且不太可能偏袒其中一个;但如果不检查实际的标记化代码,您将无法以一种或另一种方式确认
  • 这很奇怪,根据问题的 cmets,filter_var 使用类似于@Amal Murali 的正则表达式。然而它的表现稍微好一点!
  • 你知道为什么它不正确。重复是没有用的。
  • @YourCommonSense:你为什么认为它是“重复的”?你能告诉我一个真正回答OP问题的问题吗?如果是这样,我会删除我的答案。
猜你喜欢
  • 1970-01-01
  • 2011-01-09
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 2022-10-13
相关资源
最近更新 更多