Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetOrdinal optimize #253

Merged
merged 2 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions source/Sylvan.Data.Csv/CsvDataReader+Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ public override async Task<bool> ReadAsync(CancellationToken cancellationToken)
cancellationToken.ThrowIfCancellationRequested();

this.rowNumber++;
this.colCacheIdx = 0;
if (this.state == State.Open)
{
var success = await this.NextRecordAsync(cancellationToken).ConfigureAwait(false);
Expand Down
1 change: 1 addition & 0 deletions source/Sylvan.Data.Csv/CsvDataReader+Sync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ int FillBuffer()
public override bool Read()
{
this.rowNumber++;
this.colCacheIdx = 0;
if (this.state == State.Open)
{
var success = this.NextRecord();
Expand Down
39 changes: 31 additions & 8 deletions source/Sylvan.Data.Csv/CsvDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ enum ReadResult
FieldInfo[] fieldInfos;
CsvColumn[] columns;

struct OrdinalCache
{
internal string name;
internal int idx;
}

OrdinalCache[] colCache = Array.Empty<OrdinalCache>();
int colCacheIdx;

// An exception that was created with initializing, and should be thrown on the next call to Read/ReadAsync
Exception? pendingException;

Expand Down Expand Up @@ -347,6 +356,7 @@ public void Initialize()
}
}
}
this.colCache = new OrdinalCache[this.fieldCount];
this.state = hasHeaders ? State.Open : State.Initialized;
}

Expand Down Expand Up @@ -1506,18 +1516,31 @@ public override string GetName(int ordinal)
return columns[ordinal].ColumnName;
}

[MethodImpl(MethodImplOptions.NoInlining)]
int LookupOrdinal(string name)
{
var columnIndex = this.headerMap.TryGetValue(name, out var idx) ? idx : throw new IndexOutOfRangeException();
if (columnIndex == -1)
throw new AmbiguousColumnException(name);
return idx;
}

/// <inheritdoc/>
public override int GetOrdinal(string name)
{
if (this.headerMap.TryGetValue(name, out var idx))
if (name == null) throw new ArgumentNullException(nameof(name));

if (colCacheIdx < colCache.Length)
{
if (idx == -1)
ref var col = ref colCache[colCacheIdx];
colCacheIdx++;
if (!ReferenceEquals(name, col.name))
{
throw new AmbiguousColumnException(name);
col = new OrdinalCache { name = name, idx = LookupOrdinal(name) };
}
return idx;
return col.idx;
}
throw new IndexOutOfRangeException();
return LookupOrdinal(name);
}

/// <inheritdoc/>
Expand All @@ -1526,9 +1549,9 @@ public override string GetString(int ordinal)
ValidateState();
return GetStringRaw(ordinal);
}
string GetStringRaw(int ordinal)
{

string GetStringRaw(int ordinal)
{
if ((uint)ordinal < (uint)curFieldCount)
{
var s = GetFieldUnsafe(ordinal);
Expand Down
Loading