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];}
string[] dbg = ["-debug", "-gc"];
string[] optimize = ["-O", "-inline", "-release"];
string[] profile = ["-O", "-inline", "-release", "-gc"];
string[] optimize = ["-O", "-inline", "-release", "-noboundscheck"];
string[] profile = ["-O", "-release", "-noboundscheck", "-gc"];
string[] lib_src = ["dyaml/", "yaml.d"];
void compile_(string[] args, string[] files)

View file

@ -219,7 +219,7 @@ final class Parser
if(!currentEvent_.isNull)
{
immutable Event result = currentEvent_;
clear(currentEvent_);
currentEvent_.id = EventID.Invalid;
return result;
}
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);
*ptr = T(args);
//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;
}
@ -193,8 +193,8 @@ T* allocate(T, Args...)(Args args)
void free(T)(T* ptr)
{
//GC doesn't need to care about any references in this struct anymore.
if(hasIndirections!T){GC.removeRange(cast(void*)ptr);}
clear(*ptr);
static if(hasIndirections!T){GC.removeRange(cast(void*)ptr);}
static if(hasMember!(T, "__dtor")){clear(*ptr);}
std.c.stdlib.free(ptr);
}

View file

@ -170,22 +170,36 @@ final class Reader
*
* Params: length = Number of characters to get.
*
* Returns: Characters starting at current position.
*
* Throws: ReaderException if trying to read past the end of the stream
* or if invalid data is read.
* Returns: Characters starting at current position or an empty slice if out of bounds.
*/
dstring prefix(in size_t length)
const(dstring) prefix(in size_t length)
{
if(length == 0){return "";}
if(buffer_.length <= bufferOffset_ + length)
{
updateBuffer(length);
return slice(0, length);
}
const end = min(buffer_.length, bufferOffset_ + length);
//need to duplicate as we change buffer content with C functions
//and could end up with returned string referencing changed data
return cast(dstring)buffer_[bufferOffset_ .. end];
/**
* 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(end);
}
end += bufferOffset_;
start += bufferOffset_;
end = min(buffer_.length, 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
* 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
* or if invalid data is read.
@ -324,7 +338,7 @@ final class Reader
///Get next character from the stream.
dchar getDChar()
{
switch(encoding_)
final switch(encoding_)
{
case Encoding.UTF_8:
//Temp buffer for moving data in rawBuffer8_.
@ -389,7 +403,6 @@ final class Reader
available_ -= 4;
stream_.read(result);
return result;
default: assert(false);
}
}

View file

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