Replaced possibleSimpleKeys associative array in Scanner with an
ordinary array, added a mixin to generate fast lookup tables for character search, and used said mixin in the greatest bottlenecks. Another great speedup, at least 20%, can't keep track of it anymore.
This commit is contained in:
parent
97693b4417
commit
97bdf819fa
4 changed files with 147 additions and 22 deletions
102
dyaml/fastcharsearch.d
Normal file
102
dyaml/fastcharsearch.d
Normal file
|
@ -0,0 +1,102 @@
|
|||
|
||||
// Copyright Ferdinand Majerech 2011.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
module dyaml.fastcharsearch;
|
||||
|
||||
|
||||
import std.algorithm;
|
||||
import std.conv;
|
||||
|
||||
|
||||
package:
|
||||
|
||||
/**
|
||||
* Mixin used for fast searching for a character in string.
|
||||
*
|
||||
* Creates a lookup table to quickly determine if a character
|
||||
* is present in the string. Size of the lookup table is limited;
|
||||
* any characters not represented in the table will be checked
|
||||
* by ordinary equality comparison.
|
||||
*
|
||||
* Params: chars = String to search in.
|
||||
* tableSize = Maximum number of bytes used by the table.
|
||||
*
|
||||
* Generated method:
|
||||
* bool canFind(dchar c)
|
||||
*
|
||||
* Determines if a character is in the string.
|
||||
*/
|
||||
template FastCharSearch(dstring chars, uint tableSize = 256)
|
||||
{
|
||||
private mixin(searchCode!(chars, tableSize)());
|
||||
}
|
||||
|
||||
///Generate the search table and the canFind method.
|
||||
string searchCode(dstring chars, uint tableSize)()
|
||||
{
|
||||
const tableSizeStr = to!string(tableSize);
|
||||
ubyte[tableSize] table;
|
||||
table[] = 0;
|
||||
|
||||
//Characters that don't fit in the table.
|
||||
dchar[] specialChars;
|
||||
|
||||
foreach(c; chars)
|
||||
{
|
||||
if(c < tableSize){table[c] = 1;}
|
||||
else {specialChars ~= c;}
|
||||
}
|
||||
|
||||
string tableCode()
|
||||
{
|
||||
string code = "static immutable ubyte table_[" ~ tableSizeStr ~ "] = [\n";
|
||||
foreach(c; table[0 .. $ - 1])
|
||||
{
|
||||
code ~= c ? "true,\n" : "false,\n";
|
||||
}
|
||||
code ~= table[$ - 1] ? "true\n" : "false\n";
|
||||
code ~= "];\n\n";
|
||||
return code;
|
||||
}
|
||||
|
||||
string specialCharsCode()
|
||||
{
|
||||
string code;
|
||||
foreach(c; specialChars[0 .. $ - 1])
|
||||
{
|
||||
code ~= "cast(uint)c == " ~ to!string(cast(uint)c) ~ " || ";
|
||||
}
|
||||
code ~= "cast(uint)c == " ~ to!string(cast(uint)specialChars[$ - 1]);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
string code = tableSize ? tableCode() : "";
|
||||
|
||||
code ~= "bool canFind(in dchar c) pure\n"
|
||||
"{\n";
|
||||
|
||||
if(tableSize)
|
||||
{
|
||||
code ~= specialChars.length
|
||||
?
|
||||
" if(c < " ~ tableSizeStr ~ ")\n"
|
||||
" {\n"
|
||||
" return cast(bool)table_[c];\n"
|
||||
" }\n"
|
||||
:
|
||||
" return cast(bool)table_[c];\n";
|
||||
}
|
||||
if(specialChars.length)
|
||||
{
|
||||
code ~= " return " ~ specialCharsCode() ~ ";\n";
|
||||
}
|
||||
|
||||
code ~= " assert(false);\n"
|
||||
"}\n";
|
||||
|
||||
return code;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue