Last active
December 29, 2023 14:03
-
-
Save pjmagee/f9d014921446ae25affd0e3aa9d533de to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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