我正在用纯PHP创建一个Web应用程序,我必须在函数之间交换一些状态,这个状态可以是5左右,例如:user_created、user_active、user_inactive等等。那么,最有效的方法是什么呢?
最初,我从函数返回字符串,但我知道字符串比较可能会很慢,如果状态的名称越来越长,那么更多,所以我想用整数值创建常量,但它让我思考......如果PHP解析器在比较之前仍然需要读取整个常量名称,这与使用字符串或变量不是一样的吗?有没有更有效的方法呢?
对不起,如果它看起来像一个微不足道的问题,我只是试图优化我的应用程序的每个方面
如果不完全清楚我要做的很简单:
function getUserStatus() {
// return some value
}
然后按如下方式使用它
$userStatus = getUserStatus();
switch ($userStatus) {
// all possible cases
}
3条答案
按热度按时间plicqrtu1#
我将从几个方面回答你的问题,希望能让你有更广泛的理解。
对于您的实际问题,答案是应用程序的运行时阶段和解析阶段是不同的概念。PHP确实需要解析源代码,但源代码随后会被转换为另一种称为操作码的格式。操作码是代码的更低级别、更有效的表示。运行时也缓存这种表示,这意味着它不必在每次调用时都解析源代码。
当你比较两个字符串时,它所花费的时间取决于最短字符串的长度(一般来说)。然而,整数通常可以更有效地进行比较,这就是您试图通过使用基于整数的常量来实现的性能优势。查找常量的值不一定需要将常量的名称作为字符串遍历,因为它在操作码中的表示形式不一定与在源代码中的表示形式相同。然而,正如在另一个答案中所指出的,似乎PHP实际上是针对字符串比较进行优化的,并且它们实际上在很小程度上优于常量整数比较!
但是,这并不一定意味着您不应该切换到常量。对于这些类型的比较,使用常量与字符串文字的真正好处是,运行时能够在您(比如说)输入错误时帮助您。如果您的代码库中到处都是
$var == "some special value"
类型的字符串比较,解析器非常乐意让您在代码的模糊区域引入"some special value"
中的拼写错误。但是,如果您使用常量,则如果您输入了常量名称,则$var == MY_SPECIAL_CONSTANT
之类的比较将发出警告。它还允许您在一个地方定义具体的值(常量定义),这样,如果您需要更改它,只需一行更改,而不是大量的查找-替换工作。许多PHP代码倾向于“基于字符串的编程”,这些类型的代码库可能很脆弱,很容易受到错别字的影响。常量在这方面确实有帮助,而这正是它们真正的价值所在,而不是性能。
mfuanj7w2#
你可以用下面这样的东西来测试它。
请注意,PHP优化了很多,并将编译后的字节码存储在其缓存中。http://php.net/manual/en/intro.opcache.php
其结果
字符串0.38328790664673常量0.50211310386658
字符串0.38391804695129常量0.51568698883057
令我惊讶的是,String似乎更快。
我在opcache配置中注意到以下设置:
一个非常整洁的设置,有0个文档。PHP使用一种称为字符串interning的技术来提高性能,例如,如果您在代码中使用字符串“foobar”1000次,PHP将在内部为该字符串存储1个不可变变量,并在其他999次使用它时使用指向它的指针。酷,这个设置让它更上一层楼了。不是为每个单个php-fpm进程设置一个这些不可变字符串池,而是在所有php-fpm进程中共享它。它可以节省内存并提高性能,尤其是在大型应用程序中。
所以说字符串比较比常量比较慢是PHP中的一个错误假设。
但是:你可以打破这个优化的例子:
其结果将是:字符串0.61401081085205常量0.51961803436279
在这种情况下,恒定比较将更快。
性能改进添加到PHP5.4中,这里是RFC https://wiki.php.net/rfc/performanceimprovements
但是请注意,常量通常有助于更好地重构代码,因此更易于维护。此外,性能影响可以忽略不计
我的php版本:
ej83mcc03#
我知道字符串比较可能会很慢
这在Web应用程序的上下文中并不准确。
字符串比较需要 * 微秒 *。
加载一个网页,访问一个数据库等需要 * 毫秒 * 或 * 秒 *(数千倍)。
因此,这种微优化几乎不值得。相反,你应该把注意力集中在如何编写最清晰、最易维护的代码上。
如果您要循环处理数百万个项目或每秒处理数千个请求,那么代码的性能优化将在稍后发挥作用。
如果PHP解析器在比较之前仍然需要读取整个常量名称,这与使用字符串或变量不是一样的吗?
使用常量(并且常量的值是 numbers 而不是字符串)可能比使用字符串值稍微快一点,并且可能更清晰和可维护的代码。但是,在加载网页的过程中,您将无法区分。