[RFC] [VOTE] Constant scalar expressions

php.internals

Bob Weinand

12 years ago
Hi, I just have moved the RFC to vote as there was no negative feedback nor unresolved issues. Find the vote (and the RFC) at: https://wiki.php.net/rfc/const_scalar_exprs#vote Vote will last for one week. Bob

Rouven Weßling

12 years ago
Hello Bob, I know I'm late (and have no voting right) but O wonder how this interacts with. a) Constants defined in a different file b) Constants defined using the define() function. I couldn't find either case in the RFC or the previous discussion. Best regards Rouven

Bob Weinand

12 years ago
Am 20.11.2013 um 18:43 schrieb Rouven Weßling <me@rouvenwessling.de>:
> Hello Bob, > > I know I'm late (and have no voting right) but O wonder how this interacts with. > > a) Constants defined in a different file > b) Constants defined using the define() function. > > I couldn't find either case in the RFC or the previous discussion. > > Best regards > Rouven > >> On 20.11.2013, at 17:54, Bob Weinand <bobwei9@hotmail.com> wrote: >> >> Hi, >> >> I just have moved the RFC to vote as there was no negative feedback nor unresolved issues. >> >> Find the vote (and the RFC) at: >> >> https://wiki.php.net/rfc/const_scalar_exprs#vote >> >> Vote will last for one week. >> >> Bob
No top posting please :-) Constant evaluation order is not changed in this RFC. So, like const A = B; const B = 10; results in constant A being a string(1) "B", this RFC shows the same behavior: const A = B."1"; const B = 10; results in constant A being string(2) "B1". Using a more lazy constant evaluation is not in the scope of this RFC. Bob

Yasuo Ohgaki

12 years ago
Hi Bob, On Thu, Nov 21, 2013 at 1:54 AM, Bob Weinand <bobwei9@hotmail.com> wrote:
> I just have moved the RFC to vote as there was no negative feedback nor > unresolved issues. > > Find the vote (and the RFC) at: > > https://wiki.php.net/rfc/const_scalar_exprs#vote > > Vote will last for one week. >
It's nice feature, but I concerned about op caching. Currently, const is "constant". Therefore, constant value can be cached (i.e. hard coded in ops) This feature seems break op caching (or close the door for constant optimization at least) Is this a issue? I would like hear opinions from opcache/apc developers. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Bob Weinand

12 years ago
Am 20.11.2013 um 21:06 schrieb Yasuo Ohgaki <yohgaki@ohgaki.net>:
> Hi Bob, > > On Thu, Nov 21, 2013 at 1:54 AM, Bob Weinand <bobwei9@hotmail.com> wrote: > >> I just have moved the RFC to vote as there was no negative feedback nor >> unresolved issues. >> >> Find the vote (and the RFC) at: >> >> https://wiki.php.net/rfc/const_scalar_exprs#vote >> >> Vote will last for one week. >> > > It's nice feature, but I concerned about op caching. > Currently, const is "constant". Therefore, constant value can be cached > (i.e. hard coded in ops) > > This feature seems break op caching (or close the door for constant > optimization at least) > > Is this a issue? I would like hear opinions from opcache/apc developers. > > Regards, > > -- > Yasuo Ohgaki > yohgaki@ohgaki.net
As noted in the RFC "The patch is ready to be merged. (Opcache support is included, thanks to Dmitry)". So, Dmitry already did the patch for opcache and I assume he has done the best possible for that. Btw. opcache doesn't affect constants if I'm not wrong, because, what would you optimize here (already possible): a.php: if ($argv[1] == "include") include 'b.php'; const B = A; b.php: const A = 10; Here we can't cache anything because the constant B depends on a conditional inclusion: same problem. It's that same way resolved with the current patch. Also constant expressions (like 2+2 without constants involved) are resolved at compile time. So I can't detect any impact related to opcache. Bob

Yasuo Ohgaki

12 years ago
Hi Bob, On Thu, Nov 21, 2013 at 5:17 AM, Bob Weinand <bobwei9@hotmail.com> wrote:
> As noted in the RFC "The patch is ready to be merged. (Opcache support is > included, thanks to Dmitry)". > > So, Dmitry already did the patch for opcache and I assume he has done the > best possible for that. > > Btw. opcache doesn't affect constants if I'm not wrong, because, what > would you optimize here (already possible): > > a.php: > if ($argv[1] == "include") > include 'b.php'; > const B = A; > > b.php: > const A = 10; > > Here we can't cache anything because the constant B depends on a > conditional inclusion: same problem. > > It's that same way resolved with the current patch. > > Also constant expressions (like 2+2 without constants involved) are > resolved at compile time. > > So I can't detect any impact related to opcache. >
I thought whole point of introducing "const" while we have define() was to make constant cachable in ops. Anyway, I'll vote 'yes' in that case. Thank you. BTW, any reason why there is no constant array?
-- Yasuo Ohgaki yohgaki@ohgaki.net

Bob Weinand

12 years ago
Am 20.11.2013 um 21:55 schrieb Yasuo Ohgaki <yohgaki@ohgaki.net>:
> Hi Bob, > > On Thu, Nov 21, 2013 at 5:17 AM, Bob Weinand <bobwei9@hotmail.com> wrote: > As noted in the RFC "The patch is ready to be merged. (Opcache support is included, thanks to Dmitry)". > > So, Dmitry already did the patch for opcache and I assume he has done the best possible for that. > > Btw. opcache doesn't affect constants if I'm not wrong, because, what would you optimize here (already possible): > > a.php: > if ($argv[1] == "include") > include 'b.php'; > const B = A; > > b.php: > const A = 10; > > Here we can't cache anything because the constant B depends on a conditional inclusion: same problem. > > It's that same way resolved with the current patch. > > Also constant expressions (like 2+2 without constants involved) are resolved at compile time. > > So I can't detect any impact related to opcache. > > I thought whole point of introducing "const" while we have define() was to make > constant cachable in ops. > > Anyway, I'll vote 'yes' in that case. > > Thank you. > > BTW, any reason why there is no constant array? > > -- > Yasuo Ohgaki > yohgaki@ohgaki.net
Hi, That'd just be outside of this RFC's scope: const ABC = [1, 2]; is currently not allowed. Also you can't write ABC[0]. That'd be a whole other RFC to add array support for constants. So we could enable it for (static) properties, but why should we? Additions of arrays would be the only valid operation, but can you imagine _any_ use case where we'd need that when the only dynamic operands (constants) can't be arrays? Bob

Yasuo Ohgaki

12 years ago
Hi all, On Thu, Nov 21, 2013 at 6:11 AM, Bob Weinand <bobwei9@hotmail.com> wrote:
> That'd just be outside of this RFC's scope: > > const ABC = [1, 2]; > > is currently not allowed. Also you can't write ABC[0]. That'd be a whole > other RFC to add array support for constants. >
I understand it requires new codes(and flag) to make a constant array/object.
> So we could enable it for (static) properties, but why should we? > > Additions of arrays would be the only valid operation, but can you imagine > _any_ use case where we'd need that when the only dynamic operands ( > constants) can't be arrays? >
I just thought constant array/object is useful for application settings, etc that should not be changed. Anyway, constant variables are useful for VM/op code optimization. include('foo.php'); // const a = 123; const b = a; is allowed currently. We may restrict this behavior only to the same file, so that VM/op code optimization can be done. Currently, no expression is allowed with 'const'. Defining 'const' using another constant with the same value is useless. It's a bad coding practice in many case, I suppose. I understand use cases of scalar expressions with constants, but I'm concerned loosing door for further optimizations. (e.g. $x = $x + 123 is faster than $x = $x + a, where a is 123 in constant var hash) We may be better to restrict expressions with constants only to the same file even if we loose some benefits/flexibility in user code. Is this discussed? Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Yasuo Ohgaki

12 years ago
Hi all, On Fri, Nov 22, 2013 at 10:09 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Anyway, constant variables are useful for VM/op code optimization. > > include('foo.php'); // const a = 123; > const b = a; > > is allowed currently. We may restrict this behavior only to the same file, > so that VM/op code optimization can be done. > > Currently, no expression is allowed with 'const'. Defining 'const' using > another constant with the same value is useless. It's a bad coding > practice > in many case, I suppose. > > I understand use cases of scalar expressions with constants, but I'm > concerned > loosing door for further optimizations. (e.g. $x = $x + 123 is faster than > $x = $x + a, > where a is 123 in constant var hash) > > We may be better to restrict expressions with constants only to the same > file > even if we loose some benefits/flexibility in user code. > > Is this discussed? >
I voted 'yes', but I change my mind. Sorry. If the RFC leaves door for constant optimization, I'll vote 'yes'. Constant look up is not a simple hash look up. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Yasuo Ohgaki

12 years ago
Hi all, On Fri, Nov 22, 2013 at 10:19 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> On Fri, Nov 22, 2013 at 10:09 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: > >> Anyway, constant variables are useful for VM/op code optimization. >> >> include('foo.php'); // const a = 123; >> const b = a; >> >> is allowed currently. We may restrict this behavior only to the same file, >> so that VM/op code optimization can be done. >> >> Currently, no expression is allowed with 'const'. Defining 'const' using >> another constant with the same value is useless. It's a bad coding >> practice >> in many case, I suppose. >> >> I understand use cases of scalar expressions with constants, but I'm >> concerned >> loosing door for further optimizations. (e.g. $x = $x + 123 is faster >> than $x = $x + a, >> where a is 123 in constant var hash) >> >> We may be better to restrict expressions with constants only to the same >> file >> even if we loose some benefits/flexibility in user code. >> >> Is this discussed? >> > > I voted 'yes', but I change my mind. Sorry. > If the RFC leaves door for constant optimization, I'll vote 'yes'. > Constant look up is not a simple hash look up. >
One more additional note why I decided to vote 'no' for this. We already have dynamic constant via define(). <?php define('A', 123); define('B', A*2); echo B; // 246 ?> We can even use function return values with define(). <?php function foo() { return 123; } define('A', foo()); echo A; // 123 ?> I prefer 'const' to be a static for better performance, since we have dynamic constant by define() already. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Tjerk Meesters

12 years ago
Hi, On Fri, Nov 22, 2013 at 9:30 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Hi all, > > On Fri, Nov 22, 2013 at 10:19 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: > > > On Fri, Nov 22, 2013 at 10:09 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> > wrote: > > > >> Anyway, constant variables are useful for VM/op code optimization. > >> > >> include('foo.php'); // const a = 123; > >> const b = a; > >> > >> is allowed currently. We may restrict this behavior only to the same > file, > >> so that VM/op code optimization can be done. > >> > >> Currently, no expression is allowed with 'const'. Defining 'const' using > >> another constant with the same value is useless. It's a bad coding > >> practice > >> in many case, I suppose. > >> > >> I understand use cases of scalar expressions with constants, but I'm > >> concerned > >> loosing door for further optimizations. (e.g. $x = $x + 123 is faster > >> than $x = $x + a, > >> where a is 123 in constant var hash) > >> > >> We may be better to restrict expressions with constants only to the same > >> file > >> even if we loose some benefits/flexibility in user code. > >> > >> Is this discussed? > >> > > > > I voted 'yes', but I change my mind. Sorry. > > If the RFC leaves door for constant optimization, I'll vote 'yes'. > > Constant look up is not a simple hash look up. > > > > One more additional note why I decided to vote 'no' for this. > We already have dynamic constant via define(). > > <?php > define('A', 123); > define('B', A*2); > > echo B; // 246 > ?> > > We can even use function return values with define(). > > <?php > function foo() { > return 123; > } > > define('A', foo()); > > echo A; // 123 > ?> >
Yes, of course that's all possible, because define() is just a function and therefore the normal assignment rules apply. However, you didn't mention the biggest drawback to such an approach, which is that it creates *global* constants; there's no way to namespace them.
> I prefer 'const' to be a static for better performance, since > we have dynamic constant by define() already. >
Perhaps we'd have to consider how much performance is impacted on existing code, e.g. class A { const B = 123; } How much slower would that become if this RFC is accepted, cached or otherwise?
> > Regards, > > -- > Yasuo Ohgaki > yohgaki@ohgaki.net >
-- -- Tjerk

Yasuo Ohgaki

12 years ago
Hi Tjerk, On Fri, Nov 22, 2013 at 1:34 PM, Tjerk Meesters <tjerk.meesters@gmail.com>wrote:
> Yes, of course that's all possible, because define() is just a function > and therefore the normal assignment rules apply. However, you didn't > mention the biggest drawback to such an approach, which is that it creates > *global* constants; there's no way to namespace them. >
What was the reason why we don't have name space for define()?
>> I prefer 'const' to be a static for better performance, since >> we have dynamic constant by define() already. >> > > Perhaps we'd have to consider how much performance is impacted on existing > code, e.g. > > class A > { > const B = 123; > } > > How much slower would that become if this RFC is accepted, cached or > otherwise? >
I made a script to experiment. I have background job running on this machine, so I don't get stable result now, but embedding value is constantly faster. [yohgaki@dev tmp]$ php bench.php Time: 6.4675929546356 Time: 7.4527719020844 15.232544075653% slower Time: 7.4178550243378 14.69266968975% slower Time: 8.1120491027832 25.426092205894% slower Time: 7.4948840141296 15.883669035753% slower [yohgaki@dev tmp]$ php bench.php Time: 6.4104981422424 Time: 7.7053151130676 20.198383060014% slower Time: 8.022579908371 25.14752723358% slower Time: 7.5032601356506 17.046444272519% slower Time: 7.713919878006 20.332612331241% slower [yohgaki@dev tmp]$ cat bench.php <?php define('a', 1); const b = 1; class foo { const c = 1; } class bar extends foo {}; $start = microtime(true); for ($i=0 ; $i < 99999999; $i++) { $v = 1 + 1; } $test0 = microtime(true) - $start; echo 'Time: '. $test0 . PHP_EOL; $start = microtime(true); for ($i=0 ; $i < 99999999; $i++) { $v = 1 + a; } $test = microtime(true) - $start; echo 'Time: '. $test . ' '. (($test - $test0)/$test0)*100 . '% slower' . PHP_EOL; $start = microtime(true); for ($i=0 ; $i < 99999999; $i++) { $v = 1 + b; } $test = microtime(true) - $start; echo 'Time: '. $test . ' '. (($test - $test0)/$test0)*100 . '% slower' . PHP_EOL; $start = microtime(true); for ($i=0 ; $i < 99999999; $i++) { $v = 1 + foo::c; } $test = microtime(true) - $start; echo 'Time: '. $test . ' '. (($test - $test0)/$test0)*100 . '% slower' . PHP_EOL; $start = microtime(true); for ($i=0 ; $i < 99999999; $i++) { $v = 1 + bar::c; } $test = microtime(true) - $start; echo 'Time: '. $test . ' '. (($test - $test0)/$test0)*100 . '% slower' . PHP_EOL; ?>
-- Yasuo Ohgaki yohgaki@ohgaki.net