Skip to content

Instantly share code, notes, and snippets.

@pjmagee
Last active December 29, 2023 14:03
Show Gist options
  • Select an option

  • Save pjmagee/f9d014921446ae25affd0e3aa9d533de to your computer and use it in GitHub Desktop.

Select an option

Save pjmagee/f9d014921446ae25affd0e3aa9d533de to your computer and use it in GitHub Desktop.
#load "BenchmarkDotNet"
public void Main()
{
Advanced();
Basic();
}
public string FilePath = @"C:\Users\patri\OneDrive\Desktop\AncestryDNA.txt";
[Benchmark]
public void Advanced()
{
var items = Advanced(FilePath);
items.Dump();
}
[Benchmark]
public void Basic()
{
var items = Basic(FilePath);
items.Dump();
}
[GlobalSetup]
public void BenchmarkSetup()
{
}
public class GeneticData2
{
public string Rsid { get; set; }
public string Chromosome { get; set; }
public string Position { get; set; }
public string Allele1 { get; set; }
public string Allele2 { get; set; }
}
public class GeneticData
{
public ReadOnlyMemory<char> Rsid { get; init; }
public ReadOnlyMemory<char> Chromosome { get; init; }
public ReadOnlyMemory<char> Position { get; init; }
public ReadOnlyMemory<char> Allele1 { get; init; }
public ReadOnlyMemory<char> Allele2 { get; init; }
private static ReadOnlyMemory<char> GetField(ReadOnlyMemory<char> line, int index)
{
ReadOnlySpan<char> span = line.Span;
int fieldStart = 0; // Tracks the start position of the current field
int fieldEnd = -1; // Tracks the end position of the current field
for (int currentField = 0; currentField <= index; currentField++)
{
fieldEnd = span.Slice(fieldStart).IndexOf('\t'); // Find the end of the current field
if (fieldEnd == -1) // If no more tabs, this is the last field
{
if (currentField != index) // If it's not the requested field, return empty
{
return ReadOnlyMemory<char>.Empty;
}
fieldEnd = span.Length - fieldStart; // Set the field end to the length of the remaining span
break; // Exit the loop as we've found the last field
}
if (currentField == index) // If we've found the requested field, break out of the loop
{
break;
}
fieldStart += fieldEnd + 1; // Move the start to the beginning of the next field
}
// If the requested field is the last one, fieldEnd should be the remaining length of the span
return line.Slice(fieldStart, fieldEnd == -1 ? span.Length - fieldStart : fieldEnd);
}
public static GeneticData FromMemory(ReadOnlyMemory<char> line)
{
return new GeneticData
{
Rsid = GeneticData.GetField(line, 0),
Chromosome = GeneticData.GetField(line, 1),
Position = GeneticData.GetField(line, 2),
Allele1 = GeneticData.GetField(line, 3),
Allele2 = GeneticData.GetField(line, 4)
};
}
}
public static ImmutableArray<GeneticData> Advanced(string filePath)
{
var builder = ImmutableArray.CreateBuilder<GeneticData>();
using (FileStream stream = File.OpenRead(filePath))
using (var reader = new StreamReader(stream))
{
_ = reader.ReadLine();
string allText = reader.ReadToEnd();
ReadOnlyMemory<char> allTextSpan = allText.AsMemory();
// Process each line.
while (allTextSpan.Length > 0)
{
int nextNewLine = allTextSpan.Span.IndexOf('\n');
if (nextNewLine == -1)
{
builder.Add(GeneticData.FromMemory(allTextSpan.Dump()));
break;
}
else
{
builder.Add(GeneticData.FromMemory(allTextSpan.Slice(0, nextNewLine)));
allTextSpan = allTextSpan.Slice(nextNewLine + 1);
}
}
}
return builder.ToImmutable();
}
public static List<GeneticData2> Basic(string filePath)
{
var lines = System.IO.File.ReadAllLines(filePath);
List<GeneticData2> list = new List<GeneticData2>();
foreach (var line in lines.Skip(1))
{
var seg = line.Split('\t');
list.Add(new GeneticData2 { Rsid = seg[0], Chromosome = seg[1], Position = seg[2], Allele1 = seg[3], Allele2 = seg[4] });
}
return list;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment