Nikita Popov, a PHP and LLVM contributor, writes about regular expressions, PHP internals and compiler performance.
Commenters cite it for the regex expressive power article, fast routing with regular expressions, and PHP's hashtable implementation.
Please read this : https://nikic.github.io/2012/06/15/The-true-power-of-regular-expressions.html
RFC5322-compliant regex:
/
(?(DEFINE)
(?<addr_spec> (?&local_part) @ (?&domain) )
(?<local_part> (?&dot_atom) | (?"ed_string) | (?&obs_local_part) )
(?<domain> (?&dot_atom) | (?&domain_literal) | (?&obs_domain) )
(?<domain_literal> (?&CFWS)? \[ (?: (?&FWS)? (?&dtext) )* (?&FWS)? \] (?&CFWS)? )
(?<dtext> [\x21-\x5a] | [\x5e-\x7e] | (?&obs_dtext) )
(?<quoted_pair> \\ (?: (?&VCHAR) | (?&WSP) ) | (?&obs_qp) )
(?<dot_atom> (?&CFWS)? (?&dot_atom_text) (?&CFWS)? )
(?<dot_atom_text> (?&atext) (?: \. (?&atext) )* )
(?<atext> [a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+ )
(?<atom> (?&CFWS)? (?&atext) (?&CFWS)? )
(?<word> (?&atom) | (?"ed_string) )
(?<quoted_string> (?&CFWS)? " (?: (?&FWS)? (?&qcontent) )* (?&FWS)? " (?&CFWS)? )
(?<qcontent> (?&qtext) | (?"ed_pair) )
(?<qtext> \x21 | [\x23-\x5b] | [\x5d-\x7e] | (?&obs_qtext) )
# comments and whitespace
(?<FWS> (?: (?&WSP)* \r\n )? (?&WSP)+ | (?&obs_FWS) )
(?<CFWS> (?: (?&FWS)? (?&comment) )+ (?&FWS)? | (?&FWS) )
(?<comment> \( (?: (?&FWS)? (?&ccontent) )* (?&FWS)? \) )
(?<ccontent> (?&ctext) | (?"ed_pair) | (?&comment) )
(?<ctext> [\x21-\x27] | [\x2a-\x5b] | [\x5d-\x7e] | (?&obs_ctext)…
But I don't think that it has _anything_ to do with the individual programmers inherently understanding performance better.
There is likely a huge organizational focus on performance and more people expressly dedicated to the task because it is a higher priority for Epic. It is directly correlated to Epic's ability to deliver a successful product to game companies, whereas for browsers it is slightly more orthogonal to their success.
LLVM has a bunch of contributors who likely understand the intricacies of machine code better than either of us, and:
> Each LLVM release is a few percent slower than the last.
> The larger problem is that LLVM simply does not track compile-time regressions. While LNT tracks run-time performance over time, the same is not being done for compile-time or memory usage. The end result is that patches introduce unintentional compile-time regressions that go unnoticed, and can no longer be easily identified by the time the next release rolls out.
https://nikic.github.io/2020/05/10/Make-LLVM-fast-again.html
Interestingly enough here it was kinda but kinda not the other way around: historically PHP used a closed-addressing hash map and threaded a doubly linked list through it to maintain the insertion order.
But the dict TFA talks about doesn't use a doubly linked list, or closed addressing, its ordering is a side-effect of its implementation but not originally a core goal (memory saving and iteration speed were). It'd probably been proposed by others before but it came to wider attention after Raymond Hettinger (a core dev) proposed it a few years back[0]. PHP actually released it first[1], closely followed by pypy[2]. CPython only got around to it some time later[3]
[0] https://mail.python.org/pipermail/python-dev/2012-December/123028.html
[1] https://nikic.github.io/2014/12/22/PHPs-new-hashtable-implementation.html
[2] https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html
[3] https://docs.python.org/3/whatsnew/3.6.html?highlight=3.6#whatsnew36-compactdict
It probably will. Every release has a number of performance improvements although the release notes don't mention them. Great work like [1] [2] [3] weren't mentioned in the release notes because those notes mostly focused on feature improvements.
This work seems to be gaining momentum, if anything. The next version (1.44) will significantly improve the performance of programs that use async [4]. The next version of LLVM will be faster [5] (hopefully reversing the perf regressions in LLVM 10).
[1] - https://blog.mozilla.org/nnethercote/2020/04/24/how-to-speed-up-the-rust-compiler-in-2020/
[2] - https://blog.mozilla.org/nnethercote/2019/12/11/how-to-speed-up-the-rust-compiler-one-last-time-in-2019/
[3] - https://blog.mozilla.org/nnethercote/2019/10/11/how-to-speed-up-the-rust-compiler-some-more-in-2019/
[4] - https://ferrous-systems.com/blog/stable-async-on-embedded/
[5] - https://nikic.github.io/2020/05/10/Make-LLVM-fast-again.html
I believe it is just a naming issue. Not even sure that PHP devs have agreed on how to name the type. Internally, PHP calls them both arrays and hash tables if I understand correctly.
In Zend/zend_types.h[1] of PHP source:
typedef struct _zend_array zend_array;
typedef struct _zend_array HashTable;
struct _zend_array {
...
};
That being said AFAICT, HashTable and zend_array are used interchangeably throughout the source. I am not a C programmer, but I did write a couple of PHP extensions and that was my general understanding. Perhaps it is a compatibility issue or just used to abstract types differently in various areas of the C API.
Check out [2] for a deeper understanding of how arrays are handled internally in PHP.
[1]: https://github.com/php/php-src/blob/php-7.3.11/Zend/zend_types.h
[2]: https://nikic.github.io/2014/12/22/PHPs-new-hashtable-implementation.html
There isn't any evidence to suggest this. Slow compilation speed is mostly a consequence of priorities. See https://nikic.github.io/2020/05/10/Make-LLVM-fast-again.html and https://www.reddit.com/r/haskell/comments/45q90s/is_anything_being_done_to_remedy_the_soul/czzmbt1/.
Sure, there are some language features that can make optimizations pathological complex, but for the most part if compilation speed isn't continuously tracked and strictly enforced against new changes, you inevitably regress into a slower compiler.
For instance, the Go community is highly sensitive to compilation speed. Although the Go compiler is SSA-based like LLVM, it's very selective about the optimizations applied. The Go compiler tracks and benchmarks each phase of the compiler release-to-release to identify major regressions.