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