performance tuning for numeric tokens and parsing

This commit is contained in:
Eliot Jones
2019-12-22 18:45:33 +00:00
parent 1e29c298cf
commit e048bb8c2c
3 changed files with 20 additions and 33 deletions

View File

@@ -7,6 +7,7 @@
internal class ByteArrayInputBytes : IInputBytes internal class ByteArrayInputBytes : IInputBytes
{ {
private readonly int upperBound;
private readonly byte[] bytes; private readonly byte[] bytes;
[DebuggerStepThrough] [DebuggerStepThrough]
@@ -26,6 +27,8 @@
this.bytes = bytes.ToArray(); this.bytes = bytes.ToArray();
} }
upperBound = this.bytes.Length - 1;
currentOffset = -1; currentOffset = -1;
} }
@@ -34,20 +37,21 @@
{ {
this.bytes = bytes ?? throw new ArgumentNullException(nameof(bytes)); this.bytes = bytes ?? throw new ArgumentNullException(nameof(bytes));
currentOffset = -1; currentOffset = -1;
upperBound = bytes.Length - 1;
} }
private long currentOffset; private int currentOffset;
public long CurrentOffset => currentOffset + 1; public long CurrentOffset => currentOffset + 1;
public bool MoveNext() public bool MoveNext()
{ {
if (currentOffset == bytes.Length - 1) if (currentOffset == upperBound)
{ {
return false; return false;
} }
currentOffset++; currentOffset++;
CurrentByte = bytes[(int)currentOffset]; CurrentByte = bytes[currentOffset];
return true; return true;
} }
@@ -57,23 +61,23 @@
public byte? Peek() public byte? Peek()
{ {
if (currentOffset == bytes.Length - 1) if (currentOffset == upperBound)
{ {
return null; return null;
} }
return bytes[(int)currentOffset + 1]; return bytes[currentOffset + 1];
} }
public bool IsAtEnd() public bool IsAtEnd()
{ {
return currentOffset == bytes.Length - 1; return currentOffset == upperBound;
} }
public void Seek(long position) public void Seek(long position)
{ {
currentOffset = (int)position - 1; currentOffset = (int)position - 1;
CurrentByte = currentOffset < 0 ? (byte)0 : bytes[(int)currentOffset]; CurrentByte = currentOffset < 0 ? (byte)0 : bytes[currentOffset];
} }
public int Read(byte[] buffer, int? length = null) public int Read(byte[] buffer, int? length = null)
@@ -100,8 +104,8 @@
} }
var viableLength = (bytes.Length - currentOffset - 1); var viableLength = (bytes.Length - currentOffset - 1);
var readLength = (int)(viableLength < bytesToRead ? viableLength : bytesToRead); var readLength = viableLength < bytesToRead ? viableLength : bytesToRead;
var startFrom = (int)currentOffset + 1; var startFrom = currentOffset + 1;
Array.Copy(bytes, startFrom, buffer, 0, readLength); Array.Copy(bytes, startFrom, buffer, 0, readLength);

View File

@@ -110,10 +110,9 @@
/// <remarks> /// <remarks>
/// These values are specified in table 1 (page 12) of ISO 32000-1:2008. /// These values are specified in table 1 (page 12) of ISO 32000-1:2008.
/// </remarks> /// </remarks>
public static bool IsWhitespace(int c) public static bool IsWhitespace(byte c)
{ {
return c == 0 || c == 9 || c == 12 || c == AsciiLineFeed return c == 0 || c == 32 || c == AsciiLineFeed || c == AsciiCarriageReturn || c == 9 || c == 12;
|| c == AsciiCarriageReturn || c == ' ';
} }
public static bool IsEndOfLine(char c) => IsEndOfLine((byte) c); public static bool IsEndOfLine(char c) => IsEndOfLine((byte) c);

View File

@@ -1,8 +1,8 @@
namespace UglyToad.PdfPig.Tokens namespace UglyToad.PdfPig.Tokens
{ {
using System;
using System.Globalization; using System.Globalization;
/// <inheritdoc />
/// <summary> /// <summary>
/// PDF supports integer and real numbers. Integer objects represent mathematical integers within a certain interval centered at 0. /// PDF supports integer and real numbers. Integer objects represent mathematical integers within a certain interval centered at 0.
/// Real objects approximate mathematical real numbers, but with limited range and precision. /// Real objects approximate mathematical real numbers, but with limited range and precision.
@@ -16,22 +16,17 @@
/// <summary> /// <summary>
/// Whether the number represented has a non-zero decimal part. /// Whether the number represented has a non-zero decimal part.
/// </summary> /// </summary>
public bool HasDecimalPlaces { get; } public bool HasDecimalPlaces => decimal.Floor(Data) != Data;
/// <summary> /// <summary>
/// The value of this number as an <see langword="int"/>. /// The value of this number as an <see langword="int"/>.
/// </summary> /// </summary>
public int Int { get; } public int Int => (int) Data;
/// <summary>
/// Whether the number overflows an integer.
/// </summary>
public bool IsBiggerThanInt { get; }
/// <summary> /// <summary>
/// The value of this number as a <see langword="long"/>. /// The value of this number as a <see langword="long"/>.
/// </summary> /// </summary>
public long Long { get; } public long Long => (long) Data;
/// <summary> /// <summary>
/// The value of this number as a <see langword="double"/>. /// The value of this number as a <see langword="double"/>.
@@ -45,17 +40,6 @@
public NumericToken(decimal value) public NumericToken(decimal value)
{ {
Data = value; Data = value;
HasDecimalPlaces = decimal.Floor(value) != value;
Long = (long) value;
try
{
Int = (int) value;
}
catch (OverflowException)
{
IsBiggerThanInt = true;
}
} }
/// <inheritdoc /> /// <inheritdoc />