Skip to content

Create a high-performance ORC reader #16

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

Open
wants to merge 147 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
147 commits
Select commit Hold shift + click to select a range
c8f063f
Added initial ByteRangeProvider functionality.
ddrinka Mar 22, 2022
d9ae610
Adjust our target to .net 5.
ddrinka Mar 22, 2022
97a5b9a
Added infrastructure for a Span-based file-tail reader.
ddrinka Mar 22, 2022
2fab36f
Corrected class to interface.
ddrinka Mar 26, 2022
45b6d16
Added a statistics comparison for various data types.
ddrinka Mar 26, 2022
3e64aba
Initial work on index search.
ddrinka Mar 26, 2022
3434651
Clarified that `GetChunkLength` returns the compressed block length a…
ddrinka Mar 27, 2022
5c8e543
Added support for parsing Stripes and initial support for indexes.
ddrinka Mar 27, 2022
ddb62da
Completed initial iteration of the index parser.
ddrinka Mar 27, 2022
48dbd77
Added unit tests.
ddrinka Mar 28, 2022
f91b2dc
Adjusted the layout of RowGroupStatistics.
ddrinka Mar 28, 2022
4941f49
Include stubs for next development steps.
ddrinka Mar 30, 2022
84cec81
Added StripeColumnStatistics from Metadata section.
ddrinka Mar 30, 2022
7813ed3
Add initial integer RLE V2 optimized reader infrastructure.
akasarto Apr 4, 2022
b011923
Fix tracking of bytes read and offsets.
akasarto Apr 5, 2022
efcc0f2
Add raw optimized column readers infrastructure.
akasarto Apr 10, 2022
bfd11df
Add missing readers for ints, dates, doubles, etc..
akasarto May 18, 2022
09f5292
Proper handle PRESENT stream individual bits.
akasarto May 24, 2022
20726b4
Fix double reader.
akasarto May 25, 2022
1358c61
Fix timestamp reader.
akasarto May 25, 2022
405ef6e
Fix binary reader.
akasarto May 25, 2022
d25f347
Map positions for byte reader.
akasarto May 25, 2022
a1ae061
Reuse internal stream buffers.
akasarto May 25, 2022
c8598a3
Move reader data acquisition to top level classes.
akasarto May 26, 2022
10ad90a
Add support for parallel reads.
akasarto May 26, 2022
cadccbb
Use parallel execution only for byte range call.
akasarto Jun 1, 2022
bf85221
Add Amazon S3 byte range provider.
akasarto Jun 1, 2022
6798207
Remove caching from byte range provider.
akasarto Jun 2, 2022
d4bc7ae
Update optimized reader unit tests.
akasarto Jun 2, 2022
3ed3ba4
Fix optimized reader unit test method names.
akasarto Jun 2, 2022
9165fff
Add nullable unit tests.
akasarto Jun 3, 2022
0de996e
Add unit tests with and without nulls.
akasarto Jun 3, 2022
fd06dde
Add uri based byte range provider.
akasarto Jun 3, 2022
931bdd8
Remove HEAD request dependency.
akasarto Jun 3, 2022
dbf9127
Update unit test orc files metadata.
akasarto Jun 6, 2022
24d1e04
Separate data loading from data parsing.
akasarto Jun 6, 2022
a26b28b
Calculate ranges and reduce the number of byte requests per read.
akasarto Jun 6, 2022
9cbc33c
Add simple byte range requests caching.
akasarto Jun 9, 2022
802b7fb
Add filter unit tests
akasarto Jun 9, 2022
313fb35
Enable all test columns.
akasarto Jun 9, 2022
f1199a9
Parse unit test decimals using invariant culture.
akasarto Jun 9, 2022
44994cc
Merge pull request #10 from akasarto/unitTestDecimals
ddrinka Jun 16, 2022
67e7cb3
Add initial integer RLE V2 optimized reader infrastructure.
akasarto Apr 4, 2022
93ea3c2
Fix tracking of bytes read and offsets.
akasarto Apr 5, 2022
0dff32d
Add raw optimized column readers infrastructure.
akasarto Apr 10, 2022
6954677
Add missing readers for ints, dates, doubles, etc..
akasarto May 18, 2022
4318a44
Proper handle PRESENT stream individual bits.
akasarto May 24, 2022
e1bb435
Fix double reader.
akasarto May 25, 2022
7553670
Fix timestamp reader.
akasarto May 25, 2022
2a4c9de
Fix binary reader.
akasarto May 25, 2022
fdc90d5
Map positions for byte reader.
akasarto May 25, 2022
8c2aed6
Reuse internal stream buffers.
akasarto May 25, 2022
8b55d40
Move reader data acquisition to top level classes.
akasarto May 26, 2022
aa5b81c
Add support for parallel reads.
akasarto May 26, 2022
dd23a85
Use parallel execution only for byte range call.
akasarto Jun 1, 2022
0507b4d
Add Amazon S3 byte range provider.
akasarto Jun 1, 2022
f48da3a
Remove caching from byte range provider.
akasarto Jun 2, 2022
ebba96e
Update optimized reader unit tests.
akasarto Jun 2, 2022
83fa622
Fix optimized reader unit test method names.
akasarto Jun 2, 2022
a468f06
Add nullable unit tests.
akasarto Jun 3, 2022
f2cf967
Add unit tests with and without nulls.
akasarto Jun 3, 2022
b66a60c
Add uri based byte range provider.
akasarto Jun 3, 2022
33b474c
Remove HEAD request dependency.
akasarto Jun 3, 2022
b64d0a2
Update unit test orc files metadata.
akasarto Jun 6, 2022
e44a654
Separate data loading from data parsing.
akasarto Jun 6, 2022
1e242e7
Calculate ranges and reduce the number of byte requests per read.
akasarto Jun 6, 2022
f30ee11
Add simple byte range requests caching.
akasarto Jun 9, 2022
28b7367
Add filter unit tests
akasarto Jun 9, 2022
963c851
Enable all test columns.
akasarto Jun 9, 2022
8d710b4
Use wildcards for embedded resources.
akasarto Jul 1, 2022
3f9b484
Use properties in test assertions.
akasarto Jul 1, 2022
f95699c
No need for copying test files.
akasarto Jul 1, 2022
a62c1f3
Fix namings and typos.
akasarto Jul 1, 2022
234fdfa
Add BufferReader benchmarks.
akasarto Jul 2, 2022
4197141
Simplify loop in GetNextPatch method.
akasarto Jul 5, 2022
e1d0b85
Use derived span instead of base array.
akasarto Jul 5, 2022
297224a
Update BufferReader benchmarks.
akasarto Jul 5, 2022
384f57e
Specify EnumType indexes.
akasarto Jul 5, 2022
1e197a1
Optimize sequential bytes read.
akasarto Jul 5, 2022
e103ae7
Fix stripe dictionaries cache.
akasarto Jul 5, 2022
5f471ad
Remove SkipLocalsInit attribute.
akasarto Jul 5, 2022
985a267
Use invariant culture for tests.
akasarto Jul 5, 2022
f7259d4
Remove old git ignored data.
akasarto Jul 5, 2022
a331acd
Avoid unnecessary initializations.
akasarto Jul 5, 2022
556cfcd
Update variable names to match class.
akasarto Jul 5, 2022
8648617
Add date and timestamp filter and unit tests.
akasarto Jul 5, 2022
ebad0e4
Update nullable benchmarks.
akasarto Jul 5, 2022
bc7a8b0
Update compressed buffer length.
akasarto Jul 6, 2022
6bb7ebc
Remove unused method.
akasarto Jul 6, 2022
d8b3cd1
Drop usage of BigInteger struct.
akasarto Jul 6, 2022
d1a8f72
Drop usage of custom array pool.
akasarto Jul 6, 2022
3223bbb
Remove manual Fill method calls.
akasarto Jul 7, 2022
1781a62
Add boolean reader comments.
akasarto Jul 7, 2022
654d3b6
Merge branch 'codeReview1' into optimizedReaderReviewed
akasarto Jul 7, 2022
e15384f
Consolidate decompression method.
akasarto Jul 7, 2022
2362e80
Update decompression file name.
akasarto Jul 7, 2022
633919a
Strictly check supported byte range schemes.
akasarto Jul 7, 2022
785f1bb
Update byte range providers.
akasarto Jul 7, 2022
a2af3ed
Update OrcColumn class.
akasarto Jul 8, 2022
816be68
Use invariant culture only.
akasarto Jul 8, 2022
74a9868
Do not modify protobuf-net version.
akasarto Jul 8, 2022
7b21479
Avoid unnecessary changes in original code.
akasarto Jul 8, 2022
5b46746
Update OrcReader class.
akasarto Jul 8, 2022
bce119b
Add specialized 'TradeDataSource' sample class.
akasarto Jul 8, 2022
0da18ad
Add loop unroll benchmark.
akasarto Jul 12, 2022
6e41c3b
Remove unnecessary byte range provider params.
akasarto Jul 12, 2022
8451012
Add float and double buffers for null values as NaN.
akasarto Jul 12, 2022
5d64fd9
Manually unroll bit comparison loop.
akasarto Jul 12, 2022
6708f5f
Set RLE buffers based on used bytes.
akasarto Jul 12, 2022
13d6c6f
Remove read-only need in BufferReader struct.
akasarto Jul 20, 2022
30bf336
Allow configuration of decompression buffers.
akasarto Jul 20, 2022
278d66b
Add decompression buffers unit tests.
akasarto Jul 26, 2022
5cfb239
Update loop unroll benchmarks.
akasarto Jul 26, 2022
51478c8
Remove unnecessary old code.
akasarto Jul 26, 2022
a74d193
Simplify unit tests.
akasarto Jul 26, 2022
04a07c7
Update statistics extension methods.
akasarto Jul 26, 2022
f1fc8e7
Move constants to specialized file.
akasarto Jul 26, 2022
899e945
Use configurable decompression buffers in tail reads.
akasarto Jul 26, 2022
5fc8b41
Reduce decompression buffer default length.
akasarto Jul 26, 2022
37f65fc
General code improvements and cleanup.
akasarto Jul 26, 2022
e75bdcc
Simplify filling buffers with byte range providers.
akasarto Jul 26, 2022
02a93a1
Add smaller length for metadata decompression buffers.
akasarto Jul 26, 2022
48298f2
Calculate remaining bits only once.
akasarto Jul 27, 2022
5b47b6d
Integrate filters into columns.
akasarto Jul 27, 2022
797dd52
Revert "Integrate filters into columns."
akasarto Jul 28, 2022
044b850
Remove unnecessary decompression length parameter.
akasarto Jul 28, 2022
e7362d6
Dynamically resize byte range and decompression buffers.
akasarto Jul 29, 2022
f06291e
Remove last byte logic from booleans.
akasarto Aug 1, 2022
35a6d3d
Refactor TradeDataSource classes.
akasarto Aug 1, 2022
214c825
Add sample to read entire file.
akasarto Aug 3, 2022
a6a7a19
Improve range calculations.
akasarto Aug 3, 2022
6515896
Fix decompression issue when reading entire file.
akasarto Aug 4, 2022
56fd6ab
Fix reader not tracking correct number of values.
akasarto Aug 4, 2022
14a7688
Move RLE buffers ownership to top classes.
akasarto Aug 8, 2022
477e318
Refactor byte RLE skip functionality for remaining bits.
akasarto Aug 9, 2022
b0e8474
Add comparison of all values between readers.
akasarto Aug 9, 2022
807ed44
Ensure http byte range buffers are filled.
akasarto Aug 9, 2022
f69d150
Update TradeDataSource read sequence behavior.
akasarto Aug 9, 2022
1ade727
Boolean RLEs minor changes and cleanup.
akasarto Aug 11, 2022
1c9fa42
Fix partial zlib buffer decompression.
akasarto Aug 11, 2022
0c7391e
Fix byte range and decompression caching.
akasarto Aug 12, 2022
3e7eb69
Remove unnecessary buffer slicing.
akasarto Aug 12, 2022
9391009
Remove external class when tracking last stream ranges.
akasarto Aug 13, 2022
148d501
Update number of last range possible streams.
akasarto Aug 15, 2022
20aec07
Merge pull request #9 from akasarto/optimizedReaderReviewed
ddrinka Aug 15, 2022
10d0999
Review sample file columns and apps.
akasarto Aug 26, 2022
ab93abd
Merge pull request #11 from akasarto/refsCleanup
ddrinka Feb 8, 2023
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,6 @@ paket-files/
.idea/
*.sln.iml
launchSettings.json

# Benchamarks
**/BenchmarkDotNet.Artifacts/results
34 changes: 32 additions & 2 deletions ApacheOrcDotNet.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31129.286
# Visual Studio Version 17
VisualStudioVersion = 17.1.32319.34
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{58463841-CD45-4229-9E70-A0B74E70ADD7}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -29,6 +29,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApacheOrcDotNet.WriterTest.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApacheOrcDotNet.ReaderTest.App", "src\ApacheOrcDotNet.ReaderTest.App\ApacheOrcDotNet.ReaderTest.App.csproj", "{F3C9D56A-913A-453D-9C42-B9F467748413}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApacheOrcDotNet.OptimizedReader", "src\ApacheOrcDotNet.OptimizedReader\ApacheOrcDotNet.OptimizedReader.csproj", "{6C94BFE7-2452-42FF-A17A-4E090F2F8DBD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApacheOrcDotNet.OptimizedReader.Test", "test\ApacheOrcDotNet.OptimizedReader.Test\ApacheOrcDotNet.OptimizedReader.Test.csproj", "{AE3C0606-2210-40ED-AE93-67DBD06461BE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApacheOrcDotNet.OptimizedReaderTest.App", "src\ApacheOrcDotNet.OptimizedReaderTest.App\ApacheOrcDotNet.OptimizedReaderTest.App.csproj", "{E8C6F47D-51EE-4488-AF63-2898C01A6515}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "perf", "perf", "{23793296-3A05-4668-8967-364E6F73EE78}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MicroBenchmarks", "perf\MicroBenchmarks\MicroBenchmarks.csproj", "{F03F6A0D-A431-4A8A-9ED3-FF4690051713}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -51,6 +61,22 @@ Global
{F3C9D56A-913A-453D-9C42-B9F467748413}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3C9D56A-913A-453D-9C42-B9F467748413}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3C9D56A-913A-453D-9C42-B9F467748413}.Release|Any CPU.Build.0 = Release|Any CPU
{6C94BFE7-2452-42FF-A17A-4E090F2F8DBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C94BFE7-2452-42FF-A17A-4E090F2F8DBD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C94BFE7-2452-42FF-A17A-4E090F2F8DBD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6C94BFE7-2452-42FF-A17A-4E090F2F8DBD}.Release|Any CPU.Build.0 = Release|Any CPU
{AE3C0606-2210-40ED-AE93-67DBD06461BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE3C0606-2210-40ED-AE93-67DBD06461BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE3C0606-2210-40ED-AE93-67DBD06461BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE3C0606-2210-40ED-AE93-67DBD06461BE}.Release|Any CPU.Build.0 = Release|Any CPU
{E8C6F47D-51EE-4488-AF63-2898C01A6515}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E8C6F47D-51EE-4488-AF63-2898C01A6515}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8C6F47D-51EE-4488-AF63-2898C01A6515}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8C6F47D-51EE-4488-AF63-2898C01A6515}.Release|Any CPU.Build.0 = Release|Any CPU
{F03F6A0D-A431-4A8A-9ED3-FF4690051713}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F03F6A0D-A431-4A8A-9ED3-FF4690051713}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F03F6A0D-A431-4A8A-9ED3-FF4690051713}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F03F6A0D-A431-4A8A-9ED3-FF4690051713}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -60,6 +86,10 @@ Global
{D43761A7-6270-4C43-A2CE-2C244117F30A} = {40D373E1-A120-41E0-9D3D-1BACC719BB38}
{8FC4EFCA-35E9-4965-A2F8-52974F29E4DA} = {58463841-CD45-4229-9E70-A0B74E70ADD7}
{F3C9D56A-913A-453D-9C42-B9F467748413} = {58463841-CD45-4229-9E70-A0B74E70ADD7}
{6C94BFE7-2452-42FF-A17A-4E090F2F8DBD} = {58463841-CD45-4229-9E70-A0B74E70ADD7}
{AE3C0606-2210-40ED-AE93-67DBD06461BE} = {40D373E1-A120-41E0-9D3D-1BACC719BB38}
{E8C6F47D-51EE-4488-AF63-2898C01A6515} = {58463841-CD45-4229-9E70-A0B74E70ADD7}
{F03F6A0D-A431-4A8A-9ED3-FF4690051713} = {23793296-3A05-4668-8967-364E6F73EE78}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BAAC5D9A-83A0-432F-9987-90C49734F761}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
``` ini

BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1706 (21H2)
Intel Core i7-10750H CPU 2.60GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK=6.0.300
[Host] : .NET 5.0.17 (5.0.1722.21314), X64 RyuJIT
DefaultJob : .NET 5.0.17 (5.0.1722.21314), X64 RyuJIT


```
| Method | Mean | Error | StdDev | Rank | Allocated |
|---------------- |---------:|----------:|----------:|-----:|----------:|
| Standard | 1.770 ns | 0.0102 ns | 0.0090 ns | 2 | - |
| PatternMatching | 1.688 ns | 0.0584 ns | 0.0738 ns | 1 | - |
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Method;Job;AnalyzeLaunchVariance;EvaluateOverhead;MaxAbsoluteError;MaxRelativeError;MinInvokeCount;MinIterationTime;OutlierMode;Affinity;EnvironmentVariables;Jit;Platform;PowerPlanMode;Runtime;AllowVeryLargeObjects;Concurrent;CpuGroups;Force;HeapAffinitizeMask;HeapCount;NoAffinitize;RetainVm;Server;Arguments;BuildConfiguration;Clock;EngineFactory;NuGetReferences;Toolchain;IsMutator;InvocationCount;IterationCount;IterationTime;LaunchCount;MaxIterationCount;MaxWarmupIterationCount;MemoryRandomization;MinIterationCount;MinWarmupIterationCount;RunStrategy;UnrollFactor;WarmupCount;Mean;Error;StdDev;Rank;Allocated
Standard;DefaultJob;False;Default;Default;Default;Default;Default;Default;111111111111;Empty;RyuJit;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 5.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;1;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;1.770 ns;0.0102 ns;0.0090 ns;2;0 B
PatternMatching;DefaultJob;False;Default;Default;Default;Default;Default;Default;111111111111;Empty;RyuJit;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 5.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;1;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;1.688 ns;0.0584 ns;0.0738 ns;1;0 B
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>MicroBenchmarks.SwitchStatements-20220517-160420</title>

<style type="text/css">
table { border-collapse: collapse; display: block; width: 100%; overflow: auto; }
td, th { padding: 6px 13px; border: 1px solid #ddd; text-align: right; }
tr { background-color: #fff; border-top: 1px solid #ccc; }
tr:nth-child(even) { background: #f8f8f8; }
</style>
</head>
<body>
<pre><code>
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1706 (21H2)
Intel Core i7-10750H CPU 2.60GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK=6.0.300
[Host] : .NET 5.0.17 (5.0.1722.21314), X64 RyuJIT
DefaultJob : .NET 5.0.17 (5.0.1722.21314), X64 RyuJIT
</code></pre>
<pre><code></code></pre>

<table>
<thead><tr><th> Method</th><th>Mean</th><th>Error</th><th>StdDev</th><th>Rank</th><th>Allocated</th>
</tr>
</thead><tbody><tr><td>Standard</td><td>1.770 ns</td><td>0.0102 ns</td><td>0.0090 ns</td><td>2</td><td>-</td>
</tr><tr><td>PatternMatching</td><td>1.688 ns</td><td>0.0584 ns</td><td>0.0738 ns</td><td>1</td><td>-</td>
</tr></tbody></table>
</body>
</html>
Binary file not shown.
33 changes: 33 additions & 0 deletions perf/MicroBenchmarks/BufferFillersBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using BenchmarkDotNet.Attributes;
using System;

/*
| Method | Mean | Error | StdDev | Rank | Allocated |
|--------------- |------------:|----------:|----------:|-----:|----------:|
| FillWithLoop | 29,797.8 ns | 481.98 ns | 427.27 ns | 2 | - |
| FillWithMethod | 902.8 ns | 17.79 ns | 28.73 ns | 1 | - |
*/

namespace MicroBenchmarks
{
[RankColumn]
[MemoryDiagnoser]
public class BufferFillersBenchmarks
{
private const int size = 65_536;
private readonly byte[] _buffer = new byte[size];

[Benchmark]
public void FillWithLoop()
{
for (int i = 0; i < size; i++)
_buffer[i] = 255;
}

[Benchmark]
public void FillWithMethod()
{
_buffer.AsSpan().Fill(255);
}
}
}
56 changes: 56 additions & 0 deletions perf/MicroBenchmarks/BufferReaderBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using ApacheOrcDotNet.OptimizedReader;
using BenchmarkDotNet.Attributes;
using System.IO;

namespace MicroBenchmarks
{
[RankColumn]
[MemoryDiagnoser]
public class BufferReaderBenchmarks
{
private readonly byte[] _readBuffer1 = new byte[3];
private readonly byte[] _readBuffer2 = new byte[3];
private readonly string _testFilePath = @"BenchmarkDotNet.SampleData/optimized_reader_test_file.orc";
private readonly byte[] _testBuffer;

public BufferReaderBenchmarks()
{
using (var fileStream = File.OpenRead(_testFilePath))
{
_testBuffer = new byte[fileStream.Length];
fileStream.Read(_testBuffer);
}
}

[Benchmark]
public void TryRead()
{
var reader = new BufferReader(_testBuffer);
while (reader.TryRead(out _)) { }
}

[Benchmark]
public void TryCopyTo()
{
var reader = new BufferReader(_testBuffer);
while (reader.TryReadTo(_readBuffer1)) { }
}

[Benchmark]
public void TryRead3Bytes()
{
var reader = new BufferReader(_testBuffer);

_ = reader.TryRead(out _);
_ = reader.TryRead(out _);
_ = reader.TryRead(out _);
}

[Benchmark]
public void TryCopyTo3Bytes()
{
var reader = new BufferReader(_testBuffer);
_ = reader.TryReadTo(_readBuffer2);
}
}
}
43 changes: 43 additions & 0 deletions perf/MicroBenchmarks/ComparisonBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using ApacheOrcDotNet.OptimizedReader.Infrastructure;
using BenchmarkDotNet.Attributes;
using System;
using System.Collections.Generic;

/*
| Method | Mean | Error | StdDev | Rank | Allocated |
|------------------------------------ |----------:|----------:|----------:|-----:|----------:|
| ArrayEquality | 7.720 ns | 0.0755 ns | 0.0706 ns | 1 | - |
| DictionaryContainsKeyAndEquality | 12.429 ns | 0.0690 ns | 0.0645 ns | 2 | - |
| DictionaryTryGetValue | 13.052 ns | 0.0677 ns | 0.0633 ns | 3 | - |
*/

namespace MicroBenchmarks
{
[RankColumn]
[MemoryDiagnoser]
public class ComparisonBenchmarks
{
private const int size = 255;
private readonly StreamRange[] _buffer = new StreamRange[size];
private readonly Dictionary<int, StreamRange> _buffer2 = new();
private readonly StreamRange _testRange = new StreamRange(255, 255, 255);

public ComparisonBenchmarks()
{
for (int i = 0; i < size; i++)
{
_buffer[i] = new StreamRange(i, i, i);
_buffer2.Add(i, new StreamRange(i, i, i));
}
}

[Benchmark]
public bool ArrayEquality() => _buffer[128] == _testRange;

[Benchmark]
public bool DictionaryContainsKeyAndEquality() => _buffer2.ContainsKey(128) && _buffer[128] == _testRange;

[Benchmark]
public bool DictionaryTryGetValue() => _buffer2.TryGetValue(128, out var range) && range == _testRange;
}
}
55 changes: 55 additions & 0 deletions perf/MicroBenchmarks/LoopUnrollBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using BenchmarkDotNet.Attributes;
using System;

namespace MicroBenchmarks
{
[RankColumn]
[MemoryDiagnoser]
public class LoopUnrollBenchmarks
{
[Benchmark]
public void NormalLoop()
{
var numValuesRead = 0;
var numByteValuesRead = 1000;
Span<bool> outputValues = stackalloc bool[numByteValuesRead * 8];

for (int idx = 0; idx < numByteValuesRead; idx++)
{
var decodedByte = 0xff;

for (int bitIdx = 7; bitIdx >= 0; bitIdx--)
{
outputValues[numValuesRead++] = (decodedByte & 1 << bitIdx) != 0;
}
}
}

[Benchmark]
public void UnrolledLoop()
{
var decodedByte = 0xff;
var numValuesRead = 0;
var numByteValuesRead = 1000;
Span<bool> outputValues = stackalloc bool[numByteValuesRead * 8];

for (int idx = 0; idx < numByteValuesRead; idx++)
{
outputValues = outputValues.Slice(8);
if (outputValues.Length < 8)
break;

outputValues[0] = (decodedByte & 128) != 0;
outputValues[1] = (decodedByte & 64) != 0;
outputValues[2] = (decodedByte & 32) != 0;
outputValues[3] = (decodedByte & 16) != 0;
outputValues[4] = (decodedByte & 8) != 0;
outputValues[5] = (decodedByte & 4) != 0;
outputValues[6] = (decodedByte & 2) != 0;
outputValues[7] = (decodedByte & 1) != 0;

numValuesRead += 8;
}
}
}
}
22 changes: 22 additions & 0 deletions perf/MicroBenchmarks/MicroBenchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Content Include="BenchmarkDotNet.SampleData\*.orc">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\ApacheOrcDotNet.OptimizedReader\ApacheOrcDotNet.OptimizedReader.csproj" />
</ItemGroup>

</Project>
Loading