Decrease number of front evaluations
FreeSlave via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Aug 26 01:27:05 PDT 2015
Example:
import std.stdio;
import std.algorithm;
import std.path;
import std.file;
import std.exception;
import std.getopt;
import std.array;
import std.range;
auto algo(string fileName, string[] dirs, string[] extensions)
{
return dirs.filter!(delegate(dir) {
bool ok;
collectException(dir.isDir, ok);
return ok;
}).map!(dir => extensions
.map!(delegate(ext) {
string path = buildPath(dir, fileName ~ ext);
writefln("Map: %s", path);
return path;
}).filter!(delegate(filePath) {
bool ok;
writefln("Check: %s", filePath);
collectException(filePath.isFile, ok);
return ok;
})
).joiner;
}
void main(string[] args)
{
string fileName;
string extensionsStr;
getopt(args,
"fileName", "file name to search without extension",
&fileName,
"extensions", "list of extensions separated by ':'",
&extensionsStr
);
string[] dirs = args[1..$];
if (fileName.empty) {
stderr.writeln("File name not given");
return;
}
if (dirs.empty) {
dirs = ["."];
}
string[] extensions = extensionsStr.splitter(':').array;
if (extensions.empty) {
extensions = [".d"];
}
foreach(item; algo(fileName, dirs, extensions)) {
writefln("Found: %s", item);
}
}
When I run this it like this (assuming main.d exists):
main --fileName=main
It gives me:
Map: .\main.d
Check: .\main.d
Map: .\main.d
Check: .\main.d
Map: .\main.d
Check: .\main.d
Map: .\main.d
Found: .\main.d
In this simple example it calls map 4 times and filter 3 times.
The map transformer and filter predicate can be expensive, so I
would want to avoid redundant front evaluations.
The real code is more complicated and can be found here
https://github.com/MyLittleRobo/icontheme/blob/master/source/icontheme.d#L427
It can call filter's predicate with the same argument up to 8
times, which is not nice.
Are there ways to fix this? Should I consider writing my own
range type probably?
More information about the Digitalmars-d-learn
mailing list