Skip to content

Non-nil-aware fpc_ansistr_compare(|_equal).

Rika requested to merge runewalsh/source:cmps into main

This should speed up the general case of ansistring comparisons by using TAnsiRec fields directly for strings known to be non-nil.

Folding prechecks is debatable but I got the impression that it speeds up the main branch as well (though this might be because of too enthusiastic CMOVs: trunk compiles these if X then exit(0); if Y then exit(1); into test; prepare <zero>; CMOVcc <result>, <zero>; Jcc <epilogue> while could theoretically do the strictly better test; MOV <result>, 0; Jcc <epilogue>) @CuriousKit (sorry :P).

Benchmark: AnsistrCompareBenchmark.pas.

My results:

                                          before         after
x86-64
ansistr_compare_equal(a~f, 'Needle'):   6.1 ns/call   4.4 ns/call
ansistr_compare(a~f, 'Needle'):         8.1 ns/call   6.1 ns/call
ansistr_compare_equal(a~f, ''):         2.7 ns/call   2.7 ns/call
ansistr_compare(a~f, ''):               2.9 ns/call   2.9 ns/call

i386                                                  
ansistr_compare_equal(a~f, 'Needle'):   6.5 ns/call   4.9 ns/call
ansistr_compare(a~f, 'Needle'):         7.7 ns/call   6.7 ns/call
ansistr_compare_equal(a~f, ''):         2.2 ns/call   2.4 ns/call
ansistr_compare(a~f, ''):               2.2 ns/call   2.7 ns/call

Also improves New*Strings by avoiding taking the address.

Merge request reports