mbfl_name2encoding() uses a linear loop through the encodings, comparing
the name one by one, which is very slow. For the benchmark [1] just
looking up the name takes about 50% of run-time.
By using perfect hashing instead, we no longer have to loop over the
list, and the number of string comparisons is reduced to just a single
one. The perfect hashing table is generated using GNU gperf and amended
manually to fit in with mbstring and manually changed to reduce the
cache size.
[1] https://github.com/php/php-src/issues/12684#issuecomment-1813799924
* Split function and use _new variant to avoid redundant checks
* Precompute better array size to avoid rehashing
* Use new function to add into array instead of merging into, preventing temporary memory allocations
* Convert to regex without separate copy + lowering
We're already doing a character-wise loop after lowering, so just lower
it character by character instead of looping over it twice and
allocating memory.
* Use HASH_MAP loop because htab can never be packed
This saves additional checks.
* Move destructor to more sensible place
* Remove now unused browscap_zval_copy_ctor
* Use zend_string_release_ex variant where possible
* Implement dedicated greedy wildcard matching algorithm
This avoids compiling, allocating and caching regexes and should run in
the same complexity.
* Cache previous length instead of repeatedly recomputing it
* Add additional optimization to wildcard * matching
* Move cheap checks to the callsite
The function prologue and epilogue have a stupidly high overhead for
those 2 simple checks at the start.
We can't always-inline the reg_compare function because it contains
alloca, and the alloca is really important for performance.
Instead, move those cheap checks to the call site.
* Use specialised loop to avoid unnecessary conversions and checks
* Optimize counting loop by taking into account the prefix
* Precompute the hash values of known keys
* [ci skip] UPGRADING
* Code style
* Add a note why we have the early-skip checks in the loop
The datetime stored in the DOS time fields, which is what zip standard
uses, is local time without a timezone. There's an extension to the zip
file format since '97 that allows storing a unix timestamp (in UTC) in
the header for both the central directory and the local entries.
This patch adds support for this.
Closes GH-12548.
Similar to the fast, specialized mb_strcut implementation for UTF-8
in 1f0cf133db, this new implementation of mb_strcut for UTF-16 strings
just examines a few bytes before each cut point.
Even for short strings, the new implementation is around 2x faster.
For strings around 10,000 bytes in length, it comes out about 100-500x
faster in my microbenchmarks.
The new implementation behaves identically to the old one on valid
UTF-16 strings; a fuzzer was used to help verify this.
To get proper errors and sensible behaviour, as the current behaviour is somewhat insane and part of it should be axed ASAP.
The behaviour is mostly intact with some minor BC breaks which are mentioned in UPGRADING.
Co-authored-by: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
The current implementation uses a nested loop (for + goto), which has
complexity O(|s1| * |s2|). If we instead use a lookup table, the
complexity drops to O(|s1| + |s2|).
This is conceptually the same strategy that common C library
implementations such as glibc and musl use.
The variation with a bitvector instead of a table also gives a speed-up,
but the table variation was about 1.34x faster.
On microbenchmarks this easily gave a 5x speedup.
This can bring a 1.4-1.5% performance improvement in the Symfony
benchmark.
Closes GH-12431.
* Define doXInclude for XSLTProcessor, and test the property
This was added in 8d1427dd98, but never defined on the stub.
It was more or less fine when dynamic properties were not deprecated,
but now they throw a deprecation warning. To fix it, define on the stub.
This should also help discoverability of the functionality.
* Define cloneDocument for XSLTProcessor, and test the property
This was introduced in 5c039bbad9, but never defined on the stub.
It was more or less fine when dynamic properties were not deprecated,
but now they throw a deprecation warning. To fix it, define on the stub.
This should also help discoverability of the functionality.
This reimplements the parameter handling. Instead of quoting the strings
manually, adding them to an array, and passing that as input; use the
libxslt API to pass data verbatim to the processor.
This also simplifies the code a lot.
Closes GH-12331.
The XPath query is in accordance to spec [1]. However, we can do it in a
simpler way. We can use a custom callback function instead of a linear
search in XPath to check if a node is visible. Note that comment nodes
are handled internally by libxml2 already, so we do not need to
differentiate between node types. The callback will do an upwards
traversal of the tree until the root of the canonicalization is reached.
In practice this will speed up the application a lot.
[1] https://www.w3.org/TR/2001/REC-xml-c14n-20010315 section 2.1
Closes GH-12278.
This change makes the implementation much easier to understand, by explicitly
handling the various cases.
It fixes rounding for `0.49999999999999994`, because no loss of precision
happens by adding / subtracing `0.5` before turning the result into an integral
float. Instead the fractional parts are explicitly compared.
see GH-12143 (this fixes one of the reported cases)
Closes GH-12159 which was an alternative attempt to fix the rounding issue for
`0.49999999999999994`
This change makes checked and opened file consistent in a way that it is
using real path for stat operation in the same way like it is used for
open.
Closes GH-12067