diff --git a/.gitignore b/.gitignore
index 3babd98..f9d4413 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,5 @@ obj
packages
.tools
private.snk
-.idea
\ No newline at end of file
+.idea
+BenchmarkDotNet.Artifacts/
\ No newline at end of file
diff --git a/Crc32.NET.Benchmarks/Crc32.NET.Benchmarks.csproj b/Crc32.NET.Benchmarks/Crc32.NET.Benchmarks.csproj
new file mode 100644
index 0000000..920970e
--- /dev/null
+++ b/Crc32.NET.Benchmarks/Crc32.NET.Benchmarks.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net461;netcoreapp2.1;netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Crc32.NET.Benchmarks/Crc32.cs b/Crc32.NET.Benchmarks/Crc32.cs
new file mode 100644
index 0000000..c177a49
--- /dev/null
+++ b/Crc32.NET.Benchmarks/Crc32.cs
@@ -0,0 +1,43 @@
+using System;
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using Force.Crc32;
+
+namespace Crc32.NET.Benchmarks
+{
+ [SimpleJob(RuntimeMoniker.NetCoreApp31)]
+ public class Crc32
+ {
+ private byte[] _input;
+ private byte[] _destination;
+
+ [Params(65536)]
+ public int Size { get; set; }
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _input = new byte[Size];
+ var random = new Random();
+ random.NextBytes(_input);
+
+ _destination = new byte[4];
+ }
+
+ [Benchmark(Baseline = true)]
+ public byte[] Array()
+ {
+ var crc = new Crc32Algorithm();
+ return crc.ComputeHash(_input);
+ }
+
+#if NETCOREAPP3_1
+ [Benchmark]
+ public void Span()
+ {
+ var crc = new Crc32Algorithm();
+ crc.TryComputeHash(_input.AsSpan(), _destination.AsSpan(), out _);
+ }
+#endif
+ }
+}
diff --git a/Crc32.NET.Benchmarks/Program.cs b/Crc32.NET.Benchmarks/Program.cs
new file mode 100644
index 0000000..452ff95
--- /dev/null
+++ b/Crc32.NET.Benchmarks/Program.cs
@@ -0,0 +1,10 @@
+using System;
+using BenchmarkDotNet.Running;
+
+namespace Crc32.NET.Benchmarks
+{
+ class Program
+ {
+ static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new StandardConfig());
+ }
+}
diff --git a/Crc32.NET.Benchmarks/StandardConfig.cs b/Crc32.NET.Benchmarks/StandardConfig.cs
new file mode 100644
index 0000000..b1e6538
--- /dev/null
+++ b/Crc32.NET.Benchmarks/StandardConfig.cs
@@ -0,0 +1,23 @@
+using BenchmarkDotNet.Columns;
+using BenchmarkDotNet.Configs;
+using BenchmarkDotNet.Exporters;
+using BenchmarkDotNet.Loggers;
+
+namespace Crc32.NET.Benchmarks
+{
+ public class StandardConfig : ManualConfig
+ {
+ public StandardConfig()
+ {
+ AddColumnProvider(DefaultColumnProviders.Instance);
+ AddColumn(RankColumn.Arabic);
+
+ AddExporter(DefaultExporters.CsvMeasurements);
+ AddExporter(DefaultExporters.Csv);
+ AddExporter(DefaultExporters.Markdown);
+ AddExporter(DefaultExporters.Html);
+
+ AddLogger(ConsoleLogger.Default);
+ }
+ }
+}
diff --git a/Crc32.NET.Core.sln b/Crc32.NET.Core.sln
index 51e72af..5bdbb30 100644
--- a/Crc32.NET.Core.sln
+++ b/Crc32.NET.Core.sln
@@ -1,17 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26114.2
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30611.23
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Crc32.NET", "Crc32.NET\Crc32.NET.Core.csproj", "{E95FA3F3-4ED0-41FF-9A1F-DE80CE14A976}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Crc32.NET.Core", "Crc32.NET\Crc32.NET.Core.csproj", "{E95FA3F3-4ED0-41FF-9A1F-DE80CE14A976}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Crc32.NET.Tests", "Crc32.NET.Tests\Crc32.NET.Tests.Core.csproj", "{A602A9CA-793A-4096-A93C-799CA74519BF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Crc32.NET.Tests.Core", "Crc32.NET.Tests\Crc32.NET.Tests.Core.csproj", "{A602A9CA-793A-4096-A93C-799CA74519BF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{56B92A80-3AE8-4FD0-B1F6-3847919216DA}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Crc32.NET.Benchmarks", "Crc32.NET.Benchmarks\Crc32.NET.Benchmarks.csproj", "{13C3DDAD-50F1-4804-95A1-D54766EA1247}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -26,8 +28,15 @@ Global
{A602A9CA-793A-4096-A93C-799CA74519BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A602A9CA-793A-4096-A93C-799CA74519BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A602A9CA-793A-4096-A93C-799CA74519BF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {13C3DDAD-50F1-4804-95A1-D54766EA1247}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {13C3DDAD-50F1-4804-95A1-D54766EA1247}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {13C3DDAD-50F1-4804-95A1-D54766EA1247}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {13C3DDAD-50F1-4804-95A1-D54766EA1247}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A1461F74-929C-4C81-8E25-B44498AEEF6D}
+ EndGlobalSection
EndGlobal
diff --git a/Crc32.NET.Tests/Crc32.NET.Tests.Core.csproj b/Crc32.NET.Tests/Crc32.NET.Tests.Core.csproj
index abd6655..699d45f 100644
--- a/Crc32.NET.Tests/Crc32.NET.Tests.Core.csproj
+++ b/Crc32.NET.Tests/Crc32.NET.Tests.Core.csproj
@@ -1,6 +1,6 @@
- netcoreapp1.0;netcoreapp2.0;net461
+ netcoreapp1.0;netcoreapp2.0;netcoreapp3.1;net461
portable
Crc32.NET.Tests
Exe
@@ -40,6 +40,9 @@
$(DefineConstants);NETCORE;NETCORE20
+
+ $(DefineConstants);NETCORE;NETCORE30
+
$(DefineConstants);COREVERSION
diff --git a/Crc32.NET.Tests/ImplementationTest.cs b/Crc32.NET.Tests/ImplementationTest.cs
index 7bfe6da..2ff5fb9 100644
--- a/Crc32.NET.Tests/ImplementationTest.cs
+++ b/Crc32.NET.Tests/ImplementationTest.cs
@@ -1,4 +1,7 @@
using System;
+#if NETCORE30
+using System.Buffers.Binary;
+#endif
using System.Linq;
using System.Text;
@@ -30,7 +33,7 @@ public void ResultConsistency(string text, int offset)
Assert.That(crc2, Is.EqualTo(crc1));
}
#endif
-
+
[Test]
public void ResultConsistency2()
{
@@ -52,7 +55,28 @@ public void ResultConsistencyAsHashAlgorithm()
Console.WriteLine(crc2.ToString("X8"));
Assert.That(crc1, Is.EqualTo(crc2));
}
-#endif
+#endif
+
+#if NETCORE30
+ [Test]
+ public void ResultConsistencyAsHashAlgorithm_SpanVsArray()
+ {
+ var bytes = new byte[30000];
+ new Random().NextBytes(bytes);
+ var e = new Crc32Algorithm();
+ var c = new Crc32Algorithm();
+ var crc1 = BitConverter.ToInt32(e.ComputeHash(bytes), 0);
+
+ var dest = new byte[4];
+ Assert.That(c.TryComputeHash(bytes, dest, out var bytesWritten), Is.True);
+ Assert.That(bytesWritten, Is.EqualTo(4));
+ var crc2 = BinaryPrimitives.ReadInt32LittleEndian(dest);
+
+ Console.WriteLine(crc1.ToString("X8"));
+ Console.WriteLine(crc2.ToString("X8"));
+ Assert.That(crc1, Is.EqualTo(crc2));
+ }
+#endif
[Test]
public void PartIsWhole()
diff --git a/Crc32.NET/Crc32.NET.Core.csproj b/Crc32.NET/Crc32.NET.Core.csproj
index cec1661..a2c3035 100644
--- a/Crc32.NET/Crc32.NET.Core.csproj
+++ b/Crc32.NET/Crc32.NET.Core.csproj
@@ -1,7 +1,7 @@
1.2.1
- netstandard1.3;netstandard2.0;net20
+ netstandard1.3;netstandard2.0;netstandard2.1;net20
true
Crc32.NET