- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
嗯,不完全是这样,但这里有一个例子。谁能解释一下B和C的区别?使用魔术函数动态设置值而不是简单地在属性定义中设置值如何更快?
这是一些代码:
[root@vm-202-167-238-17 ~]# cat test.php; for d in A B C; do echo "------"; ./test.php $d; done;
#!/usr/bin/php
<?php
$className = $argv[1];
class A
{
public function __get($a)
{
return 5;
}
}
class B
{
public $a = 5;
}
class C
{
public function __get($a)
{
$this->a = 5;
return 5;
}
}
$a = new $className;
$start = microtime(true);
for ($i=0; $i < 1000000; $i++)
$b = $a->a;
$end = microtime(true);
echo (($end - $start) * 1000) ." msec\n";
------
598.90794754028 msec
------
205.48391342163 msec
------
189.7759437561 msec
最佳答案
魔术函数肯定比 PHP 中的任何其他函数都慢,应谨慎使用。这实际上是一个很好的博客主题(自动创建具有神奇功能的属性以加快速度......无论如何)。作为El Yobo声明,我修改了您的 PHP 脚本,以便测试更准确:
<?php
class A {
public function __get($a) {
return 5;
}
}
class B {
public $a = 5;
}
class C {
private $a = 5;
public function __get($a) {
return $this->a;
}
}
$classes = array('A','B','C');
header('Content-type: text/plain; charset=utf-8');
foreach ($classes as $className) {
$a = new $className;
$start = microtime(true);
for ($i=0; $i < 1000000; $i++) {
$b = $a->a;
}
$end = microtime(true);
echo 'Class ' . get_class($a) . ' = ' . (($end - $start) * 1000) ." msec\n";
}
导致
Class A = 378.85212898254 msec
Class B = 109.26413536072 msec
Class C = 423.51794242859 msec
所以,你有它。您可以清楚地看到,使用魔法函数时,其执行时间是公共(public)方法的大约 4 倍。
** 编辑 **
现在,如果您动态创建新的类属性,魔术方法只会在第一次调用,然后任何后续调用都将访问动态创建的public 属性(public 是为了向后兼容)。将 C 类更改为:
class C {
public function __get($a) {
$this->a = 5;
return 5;
}
}
会输出
Class A = 392.09413528442 msec
Class B = 110.16988754272 msec
Class C = 96.771955490112 msec
所以这就是为什么你会说:“嘿!它更快!”但是,看看我们是否将迭代次数从 1000000
减少到 10
(例如):
Class A = 0.033140182495117 msec
Class B = 0.0078678131103516 msec
Class C = 0.01215934753418 msec
C 类现在比 B 慢,因为它是对魔术方法的初始调用。我最好的猜测是 PHP 处理动态创建的属性而不是声明的属性。但经过进一步研究,这些结果可能会因操作系统、CPU arch、内存、PHP 版本等而异。因此,这些结果不能想当然,而且一般来说,魔法方法总是需要更长的时间执行而不是使用声明的公共(public)属性或调用声明的公共(public)方法。
** 编辑 2 **
这里是 D 类测试,跳过了任何具有动态属性创建的魔术方法:
class D {
public function __construct() {
$this->a = 5;
}
}
1000 次迭代产生这些结果:
Class A = 1.3999938964844 msec
Class B = 0.42200088500977 msec
Class C = 0.3960132598877 msec
Class D = 0.37002563476562 msec <-- faster
让我们将迭代次数增加到大约 1'000'000:
Class A = 380.80310821533 msec
Class B = 109.7559928894 msec
Class C = 91.224908828735 msec <-- faster ???
Class D = 96.340894699097 msec
如果魔法方法有很大的开销成本,那么现在真正的问题是:为什么当重复很多次访问相同的属性时,是
public function __get($a) {
$this->a = 5;
return 5;
}
比
快public function __construct() {
$this->a = 5;
}
在创建和访问动态属性时?
关于PHP Magic 比简单地设置类属性更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4496245/
我正在努力实现以下目标, 假设我有字符串: ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ) ) ) ) ) 我想编写一个正则
给定: 1 2 3 4 5 6
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
大家好,我卡颂。 Svelte问世很久了,一直想写一篇好懂的原理分析文章,拖了这么久终于写了。 本文会围绕一张流程图和两个Demo讲解,正确的食用方式是用电脑打开本文,跟着流程图、Demo一
身份证为15位或者18位,15位的全为数字,18位的前17位为数字,最后一位为数字或者大写字母”X“。 与之匹配的正则表达式: ?
我们先来最简单的,网页的登录窗口; 不过开始之前,大家先下载jquery的插件 本人习惯用了vs2008来做网页了,先添加一个空白页 这是最简单的的做法。。。先在body里面插入 <
1、MySQL自带的压力测试工具 Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、简单、实用的数据库文档(字典)生成工具,该工具支持CHM、Word、Excel、PDF、Html、XML、Markdown等
Go语言语法类似于C语言,因此熟悉C语言及其派生语言( C++、 C#、Objective-C 等)的人都会迅速熟悉这门语言。 C语言的有些语法会让代码可读性降低甚至发生歧义。Go语言在C语言的
我正在使用快速将 mkv 转换为 mp4 ffmpeg 命令 ffmpeg -i test.mkv -vcodec copy -acodec copy new.mp4 但不适用于任何 mkv 文件,当
我想计算我的工作簿中的工作表数量,然后从总数中减去特定的工作表。我错过了什么?这给了我一个对象错误: wsCount = ThisWorkbook.Sheets.Count - ThisWorkboo
我有一个 perl 文件,用于查看文件夹中是否存在 ini。如果是,它会从中读取,如果不是,它会根据我为它制作的模板创建一个。 我在 ini 部分使用 Config::Simple。 我的问题是,如果
尝试让一个 ViewController 通过标准 Cocoa 通知与另一个 ViewController 进行通信。 编写了一个简单的测试用例。在我最初的 VC 中,我将以下内容添加到 viewDi
我正在绘制高程剖面图,显示沿路径的高程增益/损失,类似于下面的: Sample Elevation Profile with hand-placed labels http://img38.image
嗨,所以我需要做的是最终让 regStart 和 regPage 根据点击事件交替可见性,我不太担心编写 JavaScript 函数,但我根本无法让我的 regPage 首先隐藏。这是我的代码。请简单
我有一个非常简单的程序来测量一个函数花费了多少时间。 #include #include #include struct Foo { void addSample(uint64_t s)
我需要为 JavaScript 制作简单的 C# BitConverter。我做了一个简单的BitConverter class BitConverter{ constructor(){} GetBy
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我是 Simple.Data 的新手。但我很难找到如何进行“分组依据”。 我想要的是非常基本的。 表格看起来像: +________+ | cards | +________+ | id |
我现在正在开发一个 JS UDF,它看起来遵循编码。 通常情况下,由于循环计数为 2,Alert Msg 会出现两次。我想要的是即使循环计数为 3,Alert Msg 也只会出现一次。任何想法都
我是一名优秀的程序员,十分优秀!