Skip to content
View ArtUkrainskiy's full-sized avatar
🏠
Working from home
🏠
Working from home

Block or report ArtUkrainskiy

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Content in all repositories owned by your account will be closed.
Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
ArtUkrainskiy/README.md

Artem Ukrainskiy

Software engineer and team lead with 15 years of experience. I have worked in product and outsourcing teams, as a developer, tech lead and team lead, on systems where load, latency and cost matter.

Blog · Habr · [email protected]

What I do

  • High-load backends: microservice design, splitting monoliths, search, caching, traffic routing and failover.
  • Data and observability: metrics pipelines, tracing, alerting, analytics on ClickHouse, decisions made from data rather than guesses.
  • Performance: profiling down to CPU instructions and memory, from application code to native extensions and the language runtime.
  • Leading teams: architecture, planning, code review, hiring, mentoring, development standards.

PHP Go Python C++ C TypeScript ClickHouse PostgreSQL MySQL MongoDB Elasticsearch Kafka RabbitMQ Laravel

Writing

Open source

php-src — performance of the PHP interpreter: string functions, json_encode(), htmlspecialchars(), CSV, the compiler, and threaded (ZTS) builds. Every change comes with measurements on Intel and AMD with several compilers, a byte-for-byte comparison with master, and the cases where it gets slower. I also review other contributors' performance PRs with the same measurements.

php-src-bench — the A/B benchmark tool behind that work, with a public report for every change: what was compared, full tables, how the output was verified, commands to reproduce.

web-request-cost — CPU and memory per request of 12 web stacks (PHP-FPM, FrankenPHP, RoadRunner, Swoole, Go, Node.js, .NET, Java and others) on PostgreSQL and MySQL, with every raw record.

Pull requests

PR Change Measured
#24448 mysqlnd: relaxed atomics instead of a mutex for statistics in ZTS builds (issue #24447) FrankenPHP + MySQL, 16 threads: 10–47% less CPU per request, depending on the cores the threads run on; statistics cost 12–91% before, 0.6–1.4% after (report)
#24283 json_encode(): decode valid UTF-8 inline non-ASCII text 9–32% fewer cycles, 6 compiler/CPU configs; with GCC 13/14 on Intel some ASCII inputs up to 20% more (report)
#24207 php_mblen() without mbrlen() for ASCII fgetcsv() 4,210 → 500 ns per row (report)
#24198 #[\Deprecated] without constructing the attribute (issue #24191) 5,016 → 2,778 instructions per deprecated call (report)
#24180 [$a, $b] = [$b, $a] without building the array 922 → 523 instructions per swap (report)
#24145 ASCII fast path in htmlspecialchars() 41–89% fewer cycles where something has to be encoded (English text, HTML, Markdown, JavaScript) (report)
#24142 html_entity_decode(): stop at the first non-name byte a string of & 3.5× faster; &param= URLs in text up to 7% slower

Numbers for #24198 and #24180 are instructions on an Intel i7-13700H, #24448 is on an AMD Ryzen 9 5950X; the reports have the full tables, machines and compilers. Also reported: the benchmark CI built Symfony Demo without ext-intl, so 18% of the measured request was a polyfill (#24183).

Reviewed and measured

Performance PRs by other contributors, measured on current master with GCC 13.3, GCC 14.2, clang 18.1 and clang 20.1 (Intel i7-13700H, the flags of the official Docker image), with the output compared to master. What the measurements showed:

PR Change Result
#24080 mb_substr() on valid UTF-8 10–98% fewer cycles in nine languages, depending on bytes per character and position; the first version returned different results for UTF-8-Mobile encodings, fixed in the PR with the suggested change
#23189 var_export() without temporary strings 15–68% fewer cycles on small and medium values; on 32-bit builds the escaped length overflowed and var_export() crashed; long strings got slower; a one-pass variant was faster than master in every case measured (report)
#23789 SSE2/NEON bin2hex()/hex2bin() hex2bin() returned wrong bytes on big-endian AArch64, two-line fix; short inputs 1–4% more cycles (report)
#24188 hash_pbkdf2() with precomputed HMAC states 43–53% fewer cycles at 1,000 iterations (35% for whirlpool), 0–5% more at 1 iteration; the hash contexts that hold the key should be wiped before freeing
#23961 charset lookup of the HTML functions, UTF-8 first short UTF-8 strings 18–27% fewer cycles on top of #23957; with clang 18 "MacRoman" +35% cycles (report)
#24157 array_push() of several values in bulk 9–38% fewer cycles for three or more values; three mutations passed the tests, two short tests suggested that catch them
#23517 array_shift() with one memmove() draining a queue of 1,000 ints 82–84% fewer cycles
#22648 array_diff() with a bitset for ints ints 71–88% fewer cycles; arrays of strings pay +1–7% for the check
#23110 unserialize() back-reference lookup 14–31% fewer cycles on payloads with many references
#23675 SSE2/NEON path in json_encode() mostly-ASCII strings of 256 bytes and more 1.3–5× faster; Cyrillic and CJK text 4–19% slower with GCC

Pinned Loading

  1. php/php-src php/php-src Public

    The PHP Interpreter

    C 41.7k 8.5k

  2. php-src-bench php-src-bench Public

    A/B micro-benchmarks for php-src

    PHP