[Issue 10675] New: [Optimizer] optimize x >= a && x <= b and such to one comparison
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Jul 19 13:20:18 PDT 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10675
Summary: [Optimizer] optimize x >= a && x <= b and such to one
comparison
Product: D
Version: D2
Platform: All
OS/Version: All
Status: NEW
Severity: enhancement
Priority: P2
Component: DMD
AssignedTo: nobody at puremagic.com
ReportedBy: dmitry.olsh at gmail.com
--- Comment #0 from Dmitry Olshansky <dmitry.olsh at gmail.com> 2013-07-19 13:20:16 PDT ---
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);
}
}
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list