1 2 module dyaml.yaml_bench; 3 //Benchmark that loads, and optionally extracts data from and/or emits a YAML file. 4 5 import std.conv; 6 import std.datetime; 7 import std.stdio; 8 import std..string; 9 import dyaml.all; 10 11 ///Print help information. 12 void help() 13 { 14 string help = 15 "D:YAML benchmark\n" 16 "Copyright (C) 2011-2014 Ferdinand Majerech\n" 17 "Usage: yaml_bench [OPTION ...] [YAML_FILE]\n" 18 "\n" 19 "Loads and optionally extracts data and/or dumps a YAML file.\n" 20 "\n" 21 "Available options:\n" 22 " -h --help Show this help information.\n" 23 " -g --get Extract data from the file (using Node.as()).\n" 24 " -d --dump Dump the loaded data (to YAML_FILE.dump).\n" 25 " -r --runs=NUM Repeat parsing the file NUM times.\n" 26 " --reload Reload the file from the diskl on every repeat\n" 27 " By default, the file is loaded to memory once\n" 28 " and repeatedly parsed from memory.\n" 29 " -s --scan-only Do not execute the entire parsing process, only\n" 30 " scanning. Overrides '--dump'.\n"; 31 writeln(help); 32 } 33 34 ///Get data out of every node. 35 void extract(ref Node document) 36 { 37 void crawl(ref Node root) 38 { 39 if(root.isScalar) switch(root.tag) 40 { 41 case "tag:yaml.org,2002:null": auto value = root.as!YAMLNull; break; 42 case "tag:yaml.org,2002:bool": auto value = root.as!bool; break; 43 case "tag:yaml.org,2002:int": auto value = root.as!long; break; 44 case "tag:yaml.org,2002:float": auto value = root.as!real; break; 45 case "tag:yaml.org,2002:binary": auto value = root.as!(ubyte[]); break; 46 case "tag:yaml.org,2002:timestamp": auto value = root.as!SysTime; break; 47 case "tag:yaml.org,2002:str": auto value = root.as!string; break; 48 default: writeln("Unrecognozed tag: ", root.tag); 49 } 50 else if(root.isSequence) foreach(ref Node node; root) 51 { 52 crawl(node); 53 } 54 else if(root.isMapping) foreach(ref Node key, ref Node value; root) 55 { 56 crawl(key); 57 crawl(value); 58 } 59 } 60 61 crawl(document); 62 } 63 64 void main(string[] args) 65 { 66 bool get = false; 67 bool dump = false; 68 bool reload = false; 69 bool scanOnly = false; 70 uint runs = 1; 71 string file = null; 72 73 //Parse command line args 74 foreach(arg; args[1 .. $]) 75 { 76 auto parts = arg.split("="); 77 if(arg[0] == '-') switch(parts[0]) 78 { 79 case "--help", "-h": help(); return; 80 case "--get", "-g": get = true; break; 81 case "--dump", "-d": dump = true; break; 82 case "--reload": reload = true; break; 83 case "--scan-only", "-s": scanOnly = true; break; 84 case "--runs", "-r": runs = parts[1].to!uint; break; 85 default: writeln("\nUnknown argument: ", arg, "\n\n"); help(); return; 86 } 87 else 88 { 89 if(file !is null) 90 { 91 writeln("\nUnknown argument or file specified twice: ", arg, "\n\n"); 92 help(); 93 return; 94 } 95 96 file = arg; 97 } 98 } 99 if(file is null) 100 { 101 writeln("\nFile not specified.\n\n"); 102 help(); 103 return; 104 } 105 106 try 107 { 108 import std.file; 109 void[] fileInMemory; 110 if(!reload) { fileInMemory = std.file.read(file); } 111 void[] fileWorkingCopy = fileInMemory.dup; 112 113 // Instead of constructing a resolver/constructor with each Loader, 114 // construct them once to remove noise when profiling. 115 auto resolver = new Resolver(); 116 auto constructor = new Constructor(); 117 118 while(runs--) 119 { 120 // Loading the file rewrites the loaded buffer, so if we don't reload from 121 // disk, we need to use a copy of the originally loaded file. 122 if(reload) { fileInMemory = std.file.read(file); } 123 else { fileWorkingCopy[] = fileInMemory[]; } 124 void[] fileToLoad = reload ? fileInMemory : fileWorkingCopy; 125 if(scanOnly) 126 { 127 auto loader = Loader(fileToLoad); 128 loader.scanBench(); 129 continue; 130 } 131 auto loader = Loader(fileToLoad); 132 loader.resolver = resolver; 133 loader.constructor = constructor; 134 auto nodes = loader.loadAll(); 135 if(dump) 136 { 137 Dumper(file ~ ".dump").dump(nodes); 138 } 139 if(get) foreach(ref node; nodes) 140 { 141 extract(node); 142 } 143 } 144 } 145 catch(YAMLException e) 146 { 147 writeln("ERROR: ", e.msg); 148 } 149 }