Moved variant.d to dyaml/std/variant. Profile build doesn't inline anymore (made profiling too difficult). More optimizations, speedup (parsing only).

This commit is contained in:
Ferdinand Majerech 2011-10-29 18:21:44 +02:00
parent be5664a24d
commit 0e0113ef0e
6 changed files with 60 additions and 33 deletions

4
cdc.d
View file

@ -155,8 +155,8 @@ void main(string[] args)
if(args.length > 0 && args[$ - 1][0] != '-'){target = args[$ - 1];} if(args.length > 0 && args[$ - 1][0] != '-'){target = args[$ - 1];}
string[] dbg = ["-debug", "-gc"]; string[] dbg = ["-debug", "-gc"];
string[] optimize = ["-O", "-inline", "-release"]; string[] optimize = ["-O", "-inline", "-release", "-noboundscheck"];
string[] profile = ["-O", "-inline", "-release", "-gc"]; string[] profile = ["-O", "-release", "-noboundscheck", "-gc"];
string[] lib_src = ["dyaml/", "yaml.d"]; string[] lib_src = ["dyaml/", "yaml.d"];
void compile_(string[] args, string[] files) void compile_(string[] args, string[] files)

View file

@ -219,7 +219,7 @@ final class Parser
if(!currentEvent_.isNull) if(!currentEvent_.isNull)
{ {
immutable Event result = currentEvent_; immutable Event result = currentEvent_;
clear(currentEvent_); currentEvent_.id = EventID.Invalid;
return result; return result;
} }
assert(false, "No event left to get"); assert(false, "No event left to get");

View file

@ -185,7 +185,7 @@ T* allocate(T, Args...)(Args args)
T* ptr = cast(T*)malloc(T.sizeof); T* ptr = cast(T*)malloc(T.sizeof);
*ptr = T(args); *ptr = T(args);
//The struct might contain references to GC-allocated memory, so tell the GC about it. //The struct might contain references to GC-allocated memory, so tell the GC about it.
if(hasIndirections!T){GC.addRange(cast(void*)ptr, T.sizeof);} static if(hasIndirections!T){GC.addRange(cast(void*)ptr, T.sizeof);}
return ptr; return ptr;
} }
@ -193,8 +193,8 @@ T* allocate(T, Args...)(Args args)
void free(T)(T* ptr) void free(T)(T* ptr)
{ {
//GC doesn't need to care about any references in this struct anymore. //GC doesn't need to care about any references in this struct anymore.
if(hasIndirections!T){GC.removeRange(cast(void*)ptr);} static if(hasIndirections!T){GC.removeRange(cast(void*)ptr);}
clear(*ptr); static if(hasMember!(T, "__dtor")){clear(*ptr);}
std.c.stdlib.free(ptr); std.c.stdlib.free(ptr);
} }

View file

@ -168,24 +168,38 @@ final class Reader
* Note: This gets only a "view" into the internal buffer, * Note: This gets only a "view" into the internal buffer,
* which WILL get invalidated after other Reader calls. * which WILL get invalidated after other Reader calls.
* *
* Params: length = Number of characters to get. * Params: length = Number of characters to get.
* *
* Returns: Characters starting at current position. * Returns: Characters starting at current position or an empty slice if out of bounds.
*
* Throws: ReaderException if trying to read past the end of the stream
* or if invalid data is read.
*/ */
dstring prefix(in size_t length) const(dstring) prefix(in size_t length)
{ {
if(length == 0){return "";} return slice(0, length);
if(buffer_.length <= bufferOffset_ + length) }
/**
* Get a slice view of the internal buffer.
*
* Note: This gets only a "view" into the internal buffer,
* which WILL get invalidated after other Reader calls.
*
* Params: start = Start of the slice relative to current position.
* end = End of the slice relative to current position.
*
* Returns: Slice into the internal buffer or an empty slice if out of bounds.
*/
const(dstring) slice(size_t start, size_t end)
{
if(buffer_.length <= bufferOffset_ + end)
{ {
updateBuffer(length); updateBuffer(end);
} }
const end = min(buffer_.length, bufferOffset_ + length); end += bufferOffset_;
//need to duplicate as we change buffer content with C functions start += bufferOffset_;
//and could end up with returned string referencing changed data end = min(buffer_.length, end);
return cast(dstring)buffer_[bufferOffset_ .. end]; if(end <= start){return "";}
return cast(dstring)buffer_[start .. end];
} }
/** /**
@ -275,7 +289,7 @@ final class Reader
* If there are not enough characters in the stream, it will get * If there are not enough characters in the stream, it will get
* as many as possible. * as many as possible.
* *
* Params: length = Mimimum number of characters we need to read. * Params: length = Number of characters we need to read.
* *
* Throws: ReaderException if trying to read past the end of the stream * Throws: ReaderException if trying to read past the end of the stream
* or if invalid data is read. * or if invalid data is read.
@ -324,7 +338,7 @@ final class Reader
///Get next character from the stream. ///Get next character from the stream.
dchar getDChar() dchar getDChar()
{ {
switch(encoding_) final switch(encoding_)
{ {
case Encoding.UTF_8: case Encoding.UTF_8:
//Temp buffer for moving data in rawBuffer8_. //Temp buffer for moving data in rawBuffer8_.
@ -389,7 +403,6 @@ final class Reader
available_ -= 4; available_ -= 4;
stream_.read(result); stream_.read(result);
return result; return result;
default: assert(false);
} }
} }

View file

@ -15,6 +15,7 @@ import core.stdc.string;
import std.algorithm; import std.algorithm;
import std.array; import std.array;
import std.container;
import std.conv; import std.conv;
import std.ascii : isAlphaNum, isDigit, isHexDigit; import std.ascii : isAlphaNum, isDigit, isHexDigit;
import std.exception; import std.exception;
@ -123,7 +124,7 @@ final class Scanner
///Current indentation level. ///Current indentation level.
int indent_ = -1; int indent_ = -1;
///Past indentation levels. Used as a stack. ///Past indentation levels. Used as a stack.
int[] indents_; Array!int indents_;
///Processed tokens not yet emitted. Used as a queue. ///Processed tokens not yet emitted. Used as a queue.
Queue!Token tokens_; Queue!Token tokens_;
@ -164,7 +165,6 @@ final class Scanner
{ {
clear(tokens_); clear(tokens_);
clear(indents_); clear(indents_);
indents_ = null;
clear(possibleSimpleKeys_); clear(possibleSimpleKeys_);
possibleSimpleKeys_ = null; possibleSimpleKeys_ = null;
clear(appender_); clear(appender_);
@ -404,7 +404,7 @@ final class Scanner
while(indent_ > column) while(indent_ > column)
{ {
indent_ = indents_.back; indent_ = indents_.back;
indents_.popBack(); indents_.length = indents_.length - 1;
tokens_.push(blockEndToken(reader_.mark, reader_.mark)); tokens_.push(blockEndToken(reader_.mark, reader_.mark));
} }
} }
@ -779,7 +779,6 @@ final class Scanner
(c == '-' || (flowLevel_ == 0 && "?:"d.canFind(c)))); (c == '-' || (flowLevel_ == 0 && "?:"d.canFind(c))));
} }
///Move to the next non-space character. ///Move to the next non-space character.
void findNextNonSpace() void findNextNonSpace()
{ {
@ -1266,13 +1265,23 @@ final class Scanner
mixin FastCharSearch!" \t\0\n\r\u0085\u2028\u2029\'\"\\"d search; mixin FastCharSearch!" \t\0\n\r\u0085\u2028\u2029\'\"\\"d search;
while(!search.canFind(c)) //This is an optimized way of writing:
//while(!search.canFind(reader_.peek(length))){++length;}
outer: for(;;)
{ {
++length; const slice = reader_.slice(length, length + 32);
c = reader_.peek(length); enforce(slice.length > 0,
new Error("While reading a flow scalar", startMark,
"reached end of file", reader_.mark));
foreach(ch; slice)
{
if(search.canFind(ch)){break outer;}
++length;
}
} }
if(length > 0){appender_.put(reader_.get(length));} appender_.put(reader_.prefix(length));
reader_.forward(length);
c = reader_.peek(); c = reader_.peek();
if(quotes == ScalarStyle.SingleQuoted && if(quotes == ScalarStyle.SingleQuoted &&
@ -1338,14 +1347,15 @@ final class Scanner
{ {
uint length = 0; uint length = 0;
while(" \t"d.canFind(reader_.peek(length))){++length;} while(" \t"d.canFind(reader_.peek(length))){++length;}
const whitespaces = reader_.get(length); const whitespaces = reader_.prefix(length + 1);
dchar c = reader_.peek(); const c = whitespaces[$ - 1];
enforce(c != '\0', new Error("While scanning a quoted scalar", startMark, enforce(c != '\0', new Error("While scanning a quoted scalar", startMark,
"found unexpected end of stream", reader_.mark)); "found unexpected end of stream", reader_.mark));
if("\n\r\u0085\u2028\u2029"d.canFind(c)) if("\n\r\u0085\u2028\u2029"d.canFind(c))
{ {
reader_.forward(length);
const lineBreak = scanLineBreak(); const lineBreak = scanLineBreak();
const breaks = scanFlowScalarBreaks(startMark); const breaks = scanFlowScalarBreaks(startMark);
@ -1353,7 +1363,11 @@ final class Scanner
else if(breaks.length == 0){appender_.put(' ');} else if(breaks.length == 0){appender_.put(' ');}
appender_.put(breaks); appender_.put(breaks);
} }
else{appender_.put(whitespaces);} else
{
appender_.put(whitespaces[0 .. $ - 1]);
reader_.forward(length);
}
} }
///Scan line breaks in a flow scalar. ///Scan line breaks in a flow scalar.