<feed xmlns='http://www.w3.org/2005/Atom'>
<title>catch3, branch v3.15.3</title>
<subtitle>Progmasoft Catch3: an independently maintained C++17 test framework with a parallel runner, property checks, snapshots and structured results.</subtitle>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/'/>
<entry>
<title>v3.15.3</title>
<updated>2026-07-26T20:19:31+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-26T20:19:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=8b08d4d79514f45f7e4ce2a607ac9c94e920d1bb'/>
<id>8b08d4d79514f45f7e4ce2a607ac9c94e920d1bb</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Avoid quadratic JSON array parse behaviour in `catch_discover_tests`</title>
<updated>2026-07-26T17:51:58+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-26T11:15:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=1079da4c5f5fea2a31d795bba95eacaa2f622849'/>
<id>1079da4c5f5fea2a31d795bba95eacaa2f622849</id>
<content type='text'>
Using CMake's `string(JSON` to parse JSON array leads to quadratic
running time in number of tests, see https://gitlab.kitware.com/cmake/cmake/-/work_items/27985

This leads to _terrible_ runtime for `catch_discover_tests` when called
on binaries with lot of tests (1k+). To get reasonable runtimes, we have
to avoid using `string(JSON` to parse out the individual test objects
from the array with all tests.

This commit replaces the sane approach of using real JSON parser with
a set of terrible hacks, where we use CMake's string APIs to split the
JSON array on what looks like object boundary (`}&lt;ws&gt;*,&lt;ws&gt;*{`), and then
checking whether the resulting thing can be parsed as JSON object. If not,
we append the next piece and check again. And again, and again, until we
get a proper JSON object.

This is all around a hilariously terrible idea, however:

1) It works in practice for all tested inputs.
2) It improves the time it takes to run `catch_discover_tests` on binary
   with 1k tests from 4.2s to 1.1s and 2k tests from 16s to 3.9s.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Using CMake's `string(JSON` to parse JSON array leads to quadratic
running time in number of tests, see https://gitlab.kitware.com/cmake/cmake/-/work_items/27985

This leads to _terrible_ runtime for `catch_discover_tests` when called
on binaries with lot of tests (1k+). To get reasonable runtimes, we have
to avoid using `string(JSON` to parse out the individual test objects
from the array with all tests.

This commit replaces the sane approach of using real JSON parser with
a set of terrible hacks, where we use CMake's string APIs to split the
JSON array on what looks like object boundary (`}&lt;ws&gt;*,&lt;ws&gt;*{`), and then
checking whether the resulting thing can be parsed as JSON object. If not,
we append the next piece and check again. And again, and again, until we
get a proper JSON object.

This is all around a hilariously terrible idea, however:

1) It works in practice for all tested inputs.
2) It improves the time it takes to run `catch_discover_tests` on binary
   with 1k tests from 4.2s to 1.1s and 2k tests from 16s to 3.9s.
</pre>
</div>
</content>
</entry>
<entry>
<title>Avoid n^2 behaviour when appending script commands in catch_discover_tests</title>
<updated>2026-07-26T13:50:33+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-26T08:51:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=60c8b878292ec4afc625a807cdc3902397a408a3'/>
<id>60c8b878292ec4afc625a807cdc3902397a408a3</id>
<content type='text'>
Repeatedly calling `string(APPEND` on the same destination string
leads to quadratic running time. We avoid this by flushing the CTest
script into a file periodically, currently every 50kB of text.

This can cause _slight_ slowdown just around the flush boundary (each
file write is quite expensive, so if we flush just before the last test
is written, it hurts), but it avoids terrible performance for large
test suites.

The performance is roughly equal at 500 tests to discover, and clearly
wins at more; for 1/2/4/8 k tests, the improvements are 0.3/1.6/6.4/27 s.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Repeatedly calling `string(APPEND` on the same destination string
leads to quadratic running time. We avoid this by flushing the CTest
script into a file periodically, currently every 50kB of text.

This can cause _slight_ slowdown just around the flush boundary (each
file write is quite expensive, so if we flush just before the last test
is written, it hurts), but it avoids terrible performance for large
test suites.

The performance is roughly equal at 500 tests to discover, and clearly
wins at more; for 1/2/4/8 k tests, the improvements are 0.3/1.6/6.4/27 s.
</pre>
</div>
</content>
</entry>
<entry>
<title>Optimize adding test commands in catch_discover_tests</title>
<updated>2026-07-26T13:50:31+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-24T10:22:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=64a551e2e7edb85e4f2cd99e5737a587eb06c35b'/>
<id>64a551e2e7edb85e4f2cd99e5737a587eb06c35b</id>
<content type='text'>
The previous approach was for `add_command` to behave as append function
via concatenating the command string internally and then saving it into
`PARENT_SCOPE`. Because this in practice ended up meaning concatenating
a copy of the string inside the function and then overwriting the string
outside the function, the performance was lacking.

The new approach is for `prepare_command` to only escape &amp; return the
command from single call, and the caller is responsible for concatenating
the result. Since the actual concatenation no longer crosses function
scope boundaries, the performance is much better, even though the scaling
is still quadratic.

The new approach only takes 1/4-1/5 of the time, saving ~1s at 1k tests,
4.5s at 2k tests and 19s at 4k tests.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The previous approach was for `add_command` to behave as append function
via concatenating the command string internally and then saving it into
`PARENT_SCOPE`. Because this in practice ended up meaning concatenating
a copy of the string inside the function and then overwriting the string
outside the function, the performance was lacking.

The new approach is for `prepare_command` to only escape &amp; return the
command from single call, and the caller is responsible for concatenating
the result. Since the actual concatenation no longer crosses function
scope boundaries, the performance is much better, even though the scaling
is still quadratic.

The new approach only takes 1/4-1/5 of the time, saving ~1s at 1k tests,
4.5s at 2k tests and 19s at 4k tests.
</pre>
</div>
</content>
</entry>
<entry>
<title>Determinize the test registration order in catch_discover_tests</title>
<updated>2026-07-26T13:23:39+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-24T10:33:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=2b971368dd9ba954604f45e748fb2d46493bb7d7'/>
<id>2b971368dd9ba954604f45e748fb2d46493bb7d7</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Add Python script for benchmarking catch_discover_tests</title>
<updated>2026-07-24T21:53:50+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-24T17:12:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=f5db82a5c47cc92ec59e6216d0b63aa866b2885d'/>
<id>f5db82a5c47cc92ec59e6216d0b63aa866b2885d</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix bad ToC link in docs/command-line.md</title>
<updated>2026-07-24T21:52:44+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-24T16:29:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=dcbb2d5d84560ad729e296a0cf567c77856859e1'/>
<id>dcbb2d5d84560ad729e296a0cf567c77856859e1</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix typo in generator exception message ("Coud" -&gt; "Could")</title>
<updated>2026-07-24T15:12:50+00:00</updated>
<author>
<name>dvir arad</name>
</author>
<published>2026-07-24T12:33:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=1a9625a6e78f455b63a4bac080fb284c9ec57731'/>
<id>1a9625a6e78f455b63a4bac080fb284c9ec57731</id>
<content type='text'>
The "Could not jump to Nth element: not enough elements" message thrown
by throw_generator_exception() had "Coud" misspelled in all three places
it appears (catch_generators.hpp, catch_generators_adapters.hpp, and
catch_interfaces_generatortracker.cpp).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The "Could not jump to Nth element: not enough elements" message thrown
by throw_generator_exception() had "Coud" misspelled in all three places
it appears (catch_generators.hpp, catch_generators_adapters.hpp, and
catch_interfaces_generatortracker.cpp).
</pre>
</div>
</content>
</entry>
<entry>
<title>JSONWriter uses LUT for faster checking if a char needs escaping</title>
<updated>2026-07-23T17:10:14+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-23T17:01:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=bb8873ccd710d55a4fa7cc02d710fdb4da69cfb0'/>
<id>bb8873ccd710d55a4fa7cc02d710fdb4da69cfb0</id>
<content type='text'>
This provides nice speedup when writing strings that don't need
escaping, at about 6% in Debug build and ~40% in Release build.
If the strings do need escaping the speedup is much smaller, at
~1% in Debug and ~6% in Release build, as the cost of actually
escaping the strings dwarves the cost of checking.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This provides nice speedup when writing strings that don't need
escaping, at about 6% in Debug build and ~40% in Release build.
If the strings do need escaping the speedup is much smaller, at
~1% in Debug and ~6% in Release build, as the cost of actually
escaping the strings dwarves the cost of checking.
</pre>
</div>
</content>
</entry>
<entry>
<title>Optimize writing of non-string values to JSON</title>
<updated>2026-07-23T12:34:43+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-23T12:34:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=46bdf1a04c92e7d34ee24f95d8d8a862498eede7'/>
<id>46bdf1a04c92e7d34ee24f95d8d8a862498eede7</id>
<content type='text'>
In practice, the majority of values the JSON writer handles are
strings, but this makes the code more obvious and can still provide
a small speed-up.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In practice, the majority of values the JSON writer handles are
strings, but this makes the code more obvious and can still provide
a small speed-up.
</pre>
</div>
</content>
</entry>
</feed>
