Improved efficiency of startup methods.
- ShpReader will copy the input stream into memory just once rather than for every header. - ShpReader.CopyImageData switched to use Array.Copy since that uses some unsafe magic for speed. - In ActorInfo, cache a GetType call and prevent needless materialization in PrerequisitesOf. - In ObjectCreator, cache type and ctor lookups since these are expensive and often repeated. - Implement IReadOnlyDictionary<T, U> on Cache<T, U> to provide some supplementary functions. - In TechTree.GatherOwnedPrerequisites, rearrange a Boolean 'and' expression to evaluate expensive functions later in the chain, and use ContainsKey to speed up name check.
This commit is contained in:
@@ -12,58 +12,58 @@ namespace OpenRA.FileFormats
|
||||
{
|
||||
public static class Format40
|
||||
{
|
||||
public static int DecodeInto( byte[] src, byte[] dest )
|
||||
public static int DecodeInto(byte[] src, byte[] dest, int srcOffset)
|
||||
{
|
||||
var ctx = new FastByteReader(src);
|
||||
var ctx = new FastByteReader(src, srcOffset);
|
||||
int destIndex = 0;
|
||||
|
||||
while( true )
|
||||
while (true)
|
||||
{
|
||||
byte i = ctx.ReadByte();
|
||||
if( ( i & 0x80 ) == 0 )
|
||||
if ((i & 0x80) == 0)
|
||||
{
|
||||
int count = i & 0x7F;
|
||||
if( count == 0 )
|
||||
if (count == 0)
|
||||
{
|
||||
// case 6
|
||||
count = ctx.ReadByte();
|
||||
byte value = ctx.ReadByte();
|
||||
for( int end = destIndex + count ; destIndex < end ; destIndex++ )
|
||||
dest[ destIndex ] ^= value;
|
||||
for (int end = destIndex + count; destIndex < end; destIndex++)
|
||||
dest[destIndex] ^= value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 5
|
||||
for( int end = destIndex + count ; destIndex < end ; destIndex++ )
|
||||
for (int end = destIndex + count; destIndex < end; destIndex++)
|
||||
dest[destIndex] ^= ctx.ReadByte();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = i & 0x7F;
|
||||
if( count == 0 )
|
||||
if (count == 0)
|
||||
{
|
||||
count = ctx.ReadWord();
|
||||
if( count == 0 )
|
||||
if (count == 0)
|
||||
return destIndex;
|
||||
|
||||
if( ( count & 0x8000 ) == 0 )
|
||||
if ((count & 0x8000) == 0)
|
||||
{
|
||||
// case 2
|
||||
destIndex += ( count & 0x7FFF );
|
||||
destIndex += (count & 0x7FFF);
|
||||
}
|
||||
else if( ( count & 0x4000 ) == 0 )
|
||||
else if ((count & 0x4000) == 0)
|
||||
{
|
||||
// case 3
|
||||
for( int end = destIndex + ( count & 0x3FFF ) ; destIndex < end ; destIndex++ )
|
||||
for (int end = destIndex + (count & 0x3FFF); destIndex < end; destIndex++)
|
||||
dest[destIndex] ^= ctx.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 4
|
||||
byte value = ctx.ReadByte();
|
||||
for( int end = destIndex + ( count & 0x3FFF ) ; destIndex < end ; destIndex++ )
|
||||
dest[ destIndex ] ^= value;
|
||||
for (int end = destIndex + (count & 0x3FFF); destIndex < end; destIndex++)
|
||||
dest[destIndex] ^= value;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user