Currently DMD doesn't optimize interval-style conditions unlike GDC & LDC:
x >= a && x <= b
--->
//val size has to be big enough for the entire range of [0, b]
unsigned val = x - a;
val <= b - a
The are multitude of alternatives of the above including if/else if chains and/or seuqnce of ifs with early return like:
if(x < a)
return false;
if(x <= b
return true;
return false;
See current (soon to be replaced) std.uni:
https://github.com/D-Programming-Language/phobos/blob/master/std/uni.d#L563
Typical use-case are ASCII isAlpha/isDigit etc. functions heavily used in various lexers/scanners.
See little "benchmark". Timings are dominated by loop overhead and memory access but a significant difference is observable non the less.
import std.file;
import std.stdio, std.datetime;
//let compiler optimize if/else
size_t process1(void[] buf)
{
size_t cnt = 0;
foreach(i; 0..100)
foreach(c; cast(ubyte[])buf)
{
if(c < 0xAA)
{
if(c < 'A')
{
}
else if(c <= 'Z')
cnt++;
else if(c < 'a')
{
}
else if(c <= 'z')
cnt++;
}
}
return cnt;
}
//do our job by hand
size_t process2(void[] buf)
{
size_t cnt = 0;
foreach(i; 0..100)
foreach(c; cast(ubyte[])buf)
{
if(c < 0xAA)
{
//these x and y should be the smallest unsigned type to fit the range
size_t x = c - 'A';
if(x <= 'Z'-'A')
cnt++;
else{
size_t y = c - 'a';
if(y <= 'z' - 'a')
cnt++;
}
}
}
return cnt;
}
void main(string argv[])
{
foreach(v; argv[1..$]){
StopWatch sw;
sw.start();
version(compiler){
auto count = process1(read(v));
}
else version(manual)
auto count = process2(read(v));
else
static assert(0);
sw.stop();
writefln("%s %s ASCII alphabetic. [%d us]", v, count, sw.peek().usecs);
}
}
Comment #1 by dmitry.olsh — 2013-07-19T13:22:00Z
Created attachment 1236
Disassembly of test case
Disassembly of 2 critical if-chainy functions.
Comment #2 by dmitry.olsh — 2013-07-19T13:23:23Z
Aye, and compiler flags used.
First version:
dmd -release -O -inline -noboundscheck -version=compiler if_else_opt.d
Optimized by hand version:
dmd -release -O -inline -noboundscheck -version=manual if_else_opt.d
Comment #3 by robert.schadek — 2024-12-13T18:09:33Z