This is an automated email from the ASF dual-hosted git repository.

blankensteiner pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar-dotpulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 5357829  Added compression benchmarks
5357829 is described below

commit 53578295ad9f2552f50f6e2b05c30171e274af6e
Author: Daniel Blankensteiner <d...@vmail.dk>
AuthorDate: Wed Feb 7 12:21:59 2024 +0100

    Added compression benchmarks
---
 DotPulsar.sln                                |  9 +++
 benchmarks/Compression/Compress.cs           | 69 +++++++++++++++++++++
 benchmarks/Compression/Compression.csproj    | 32 ++++++++++
 benchmarks/Compression/Decompress.cs         | 89 ++++++++++++++++++++++++++++
 benchmarks/Compression/Factories.cs          | 64 ++++++++++++++++++++
 benchmarks/Compression/MessageBytes.cs       | 76 ++++++++++++++++++++++++
 benchmarks/Compression/MessageSize.cs        | 21 +++++++
 benchmarks/Compression/MessageType.cs        | 21 +++++++
 benchmarks/Compression/Messages.proto        | 30 ++++++++++
 benchmarks/Compression/Program.cs            | 40 +++++++++++++
 tests/DotPulsar.Tests/DotPulsar.Tests.csproj |  4 +-
 11 files changed, 453 insertions(+), 2 deletions(-)

diff --git a/DotPulsar.sln b/DotPulsar.sln
index 35c2690..1706858 100644
--- a/DotPulsar.sln
+++ b/DotPulsar.sln
@@ -26,6 +26,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = 
"Solution Items", "Solution
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Processing", 
"samples\Processing\Processing.csproj", "{CC1494FA-4EB5-4DB9-8BE9-0A6E8D0D963E}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Compression", 
"benchmarks\Compression\Compression.csproj", 
"{040F8253-074D-4977-BDB1-0D9798B52CE2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", 
"Benchmarks", "{2C57AF4B-0D23-42D7-86FE-80277FD52875}"
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Any CPU = Debug|Any CPU
@@ -56,6 +60,10 @@ Global
                {CC1494FA-4EB5-4DB9-8BE9-0A6E8D0D963E}.Debug|Any CPU.Build.0 = 
Debug|Any CPU
                {CC1494FA-4EB5-4DB9-8BE9-0A6E8D0D963E}.Release|Any 
CPU.ActiveCfg = Release|Any CPU
                {CC1494FA-4EB5-4DB9-8BE9-0A6E8D0D963E}.Release|Any CPU.Build.0 
= Release|Any CPU
+               {040F8253-074D-4977-BDB1-0D9798B52CE2}.Debug|Any CPU.ActiveCfg 
= Debug|Any CPU
+               {040F8253-074D-4977-BDB1-0D9798B52CE2}.Debug|Any CPU.Build.0 = 
Debug|Any CPU
+               {040F8253-074D-4977-BDB1-0D9798B52CE2}.Release|Any 
CPU.ActiveCfg = Release|Any CPU
+               {040F8253-074D-4977-BDB1-0D9798B52CE2}.Release|Any CPU.Build.0 
= Release|Any CPU
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
@@ -66,6 +74,7 @@ Global
                {14934BED-A222-47B2-A58A-CFC4AAB89B49} = 
{E7106D0F-B255-4631-9FB8-734FC5748FA9}
                {6D44683B-865C-4D15-9F0A-1A8441354589} = 
{E7106D0F-B255-4631-9FB8-734FC5748FA9}
                {CC1494FA-4EB5-4DB9-8BE9-0A6E8D0D963E} = 
{E7106D0F-B255-4631-9FB8-734FC5748FA9}
+               {040F8253-074D-4977-BDB1-0D9798B52CE2} = 
{2C57AF4B-0D23-42D7-86FE-80277FD52875}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {88355922-E70A-4B73-B7F8-ABF8F2B59789}
diff --git a/benchmarks/Compression/Compress.cs 
b/benchmarks/Compression/Compress.cs
new file mode 100644
index 0000000..66b7b56
--- /dev/null
+++ b/benchmarks/Compression/Compress.cs
@@ -0,0 +1,69 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Compression;
+
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Order;
+using System.Buffers;
+
+[RankColumn, Orderer(SummaryOrderPolicy.FastestToSlowest)]
+public class Compress
+{
+    [ParamsAllValues]
+    public MessageSize Size { get; set; }
+
+    [ParamsAllValues]
+    public MessageType Type { get; set; }
+
+    [GlobalSetup]
+    public void Setup() => Data = MessageBytes.GetBytes(Size, Type);
+
+    public ReadOnlySequence<byte> Data { get; private set; }
+
+    [Benchmark]
+    public void K4aosCompressionLz4()
+    {
+        using var compressor = 
Factories.K4aosCompressionLz4CompressorFactory.Create();
+        _ = compressor.Compress(Data);
+    }
+
+    [Benchmark]
+    public void IronSnappy()
+    {
+        using var compressor = Factories.IronSnappyCompressorFactory.Create();
+        _ = compressor.Compress(Data);
+    }
+
+    [Benchmark]
+    public void DotNetZip()
+    {
+        using var compressor = Factories.DotNetZipCompressorFactory.Create();
+        _ = compressor.Compress(Data);
+    }
+
+    [Benchmark]
+    public void ZstdNet()
+    {
+        using var compressor = Factories.ZstdNetCompressorFactory.Create();
+        _ = compressor.Compress(Data);
+    }
+
+    [Benchmark]
+    public void ZstdSharp()
+    {
+        using var compressor = Factories.ZstdSharpCompressorFactory.Create();
+        _ = compressor.Compress(Data);
+    }
+}
diff --git a/benchmarks/Compression/Compression.csproj 
b/benchmarks/Compression/Compression.csproj
new file mode 100644
index 0000000..288add9
--- /dev/null
+++ b/benchmarks/Compression/Compression.csproj
@@ -0,0 +1,32 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
+    <PackageReference Include="DotNetZip" Version="1.16.0" />
+    <PackageReference Include="Google.Protobuf" Version="3.25.2" />
+    <PackageReference Include="Grpc.Tools" Version="2.61.0">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; 
buildtransitive</IncludeAssets>
+    </PackageReference>
+    <PackageReference Include="IronSnappy" Version="1.3.1" />
+    <PackageReference Include="K4os.Compression.LZ4" Version="1.3.6" />
+    <PackageReference Include="ZstdNet" Version="1.4.5" />
+    <PackageReference Include="ZstdSharp.Port" Version="0.7.5" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Protobuf Include="Messages.proto" GrpcServices="None" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\DotPulsar\DotPulsar.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/benchmarks/Compression/Decompress.cs 
b/benchmarks/Compression/Decompress.cs
new file mode 100644
index 0000000..902511a
--- /dev/null
+++ b/benchmarks/Compression/Decompress.cs
@@ -0,0 +1,89 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Compression;
+
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Order;
+using System.Buffers;
+
+[RankColumn, Orderer(SummaryOrderPolicy.FastestToSlowest)]
+public class Decompress
+{
+    [ParamsAllValues]
+    public MessageSize Size { get; set; }
+
+    [ParamsAllValues]
+    public MessageType Type { get; set; }
+
+    [GlobalSetup]
+    public void Setup()
+    {
+        var data = MessageBytes.GetBytes(Size, Type);
+        DecompressedSize = (int) data.Length;
+
+        using (var compressor = 
Factories.K4aosCompressionLz4CompressorFactory.Create())
+            K4aosCompressionLz4Data = compressor.Compress(data);
+        using (var compressor = Factories.IronSnappyCompressorFactory.Create())
+            IronSnappyData = compressor.Compress(data);
+        using (var compressor = Factories.DotNetZipCompressorFactory.Create())
+            DotNetZipData = compressor.Compress(data);
+        using (var compressor = Factories.ZstdNetCompressorFactory.Create())
+            ZstdNetData = compressor.Compress(data);
+        using (var compressor = Factories.ZstdSharpCompressorFactory.Create())
+            ZstdSharpData = compressor.Compress(data);
+    }
+
+    public int DecompressedSize { get; private set; }
+    public ReadOnlySequence<byte> K4aosCompressionLz4Data { get; private set; }
+    public ReadOnlySequence<byte> IronSnappyData { get; private set; }
+    public ReadOnlySequence<byte> DotNetZipData { get; private set; }
+    public ReadOnlySequence<byte> ZstdNetData { get; private set; }
+    public ReadOnlySequence<byte> ZstdSharpData { get; private set; }
+
+    [Benchmark]
+    public void K4aosCompressionLz4()
+    {
+        using var decompressor = 
Factories.K4aosCompressionLz4DecompressorFactory.Create();
+        _ = decompressor.Decompress(K4aosCompressionLz4Data, DecompressedSize);
+    }
+
+    [Benchmark]
+    public void IronSnappy()
+    {
+        using var decompressor = 
Factories.IronSnappyDecompressorFactory.Create();
+        _ = decompressor.Decompress(IronSnappyData, DecompressedSize);
+    }
+
+    [Benchmark]
+    public void DotNetZip()
+    {
+        using var decompressor = 
Factories.DotNetZipDecompressorFactory.Create();
+        _ = decompressor.Decompress(DotNetZipData, DecompressedSize);
+    }
+
+    [Benchmark]
+    public void ZstdNet()
+    {
+        using var decompressor = Factories.ZstdNetDecompressorFactory.Create();
+        _ = decompressor.Decompress(ZstdNetData, DecompressedSize);
+    }
+
+    [Benchmark]
+    public void ZstdSharp()
+    {
+        using var decompressor = 
Factories.ZstdSharpDecompressorFactory.Create();
+        _ = decompressor.Decompress(ZstdSharpData, DecompressedSize);
+    }
+}
diff --git a/benchmarks/Compression/Factories.cs 
b/benchmarks/Compression/Factories.cs
new file mode 100644
index 0000000..045e377
--- /dev/null
+++ b/benchmarks/Compression/Factories.cs
@@ -0,0 +1,64 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Compression;
+
+using DotPulsar.Internal.Abstractions;
+using DotPulsar.Internal.Compression;
+
+public static class Factories
+{
+    static Factories()
+    {
+        if (!Lz4Compression.TryLoading(out var compressor, out var 
decompressor))
+            throw new Exception("Could not load K4os.Compression.LZ4");
+        K4aosCompressionLz4CompressorFactory = compressor!;
+        K4aosCompressionLz4DecompressorFactory = decompressor!;
+
+        if (!SnappyCompression.TryLoading(out compressor, out decompressor))
+            throw new Exception("Could not load IronSnappy");
+        IronSnappyCompressorFactory = compressor!;
+        IronSnappyDecompressorFactory = decompressor!;
+
+        if (!ZlibCompression.TryLoading(out compressor, out decompressor))
+            throw new Exception("Could not load DotNetZip");
+        DotNetZipCompressorFactory = compressor!;
+        DotNetZipDecompressorFactory = decompressor!;
+
+        if (!ZstdCompression.TryLoading(out compressor, out decompressor))
+            throw new Exception("Could not load ZstdNet");
+        ZstdNetCompressorFactory = compressor!;
+        ZstdNetDecompressorFactory = decompressor!;
+
+        if (!ZstdSharpCompression.TryLoading(out compressor, out decompressor))
+            throw new Exception("Could not load ZstdSharp");
+        ZstdSharpCompressorFactory = compressor!;
+        ZstdSharpDecompressorFactory = decompressor!;
+    }
+
+    public static ICompressorFactory K4aosCompressionLz4CompressorFactory { 
get; }
+    public static IDecompressorFactory K4aosCompressionLz4DecompressorFactory 
{ get; }
+
+    public static ICompressorFactory IronSnappyCompressorFactory { get; }
+    public static IDecompressorFactory IronSnappyDecompressorFactory { get; }
+
+    public static ICompressorFactory DotNetZipCompressorFactory { get; }
+    public static IDecompressorFactory DotNetZipDecompressorFactory { get; }
+
+    public static ICompressorFactory ZstdNetCompressorFactory { get; }
+    public static IDecompressorFactory ZstdNetDecompressorFactory { get; }
+
+    public static ICompressorFactory ZstdSharpCompressorFactory { get; }
+    public static IDecompressorFactory ZstdSharpDecompressorFactory { get; }
+}
diff --git a/benchmarks/Compression/MessageBytes.cs 
b/benchmarks/Compression/MessageBytes.cs
new file mode 100644
index 0000000..7124e5f
--- /dev/null
+++ b/benchmarks/Compression/MessageBytes.cs
@@ -0,0 +1,76 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Compression;
+
+using Compression.Messages;
+using Google.Protobuf;
+using Google.Protobuf.WellKnownTypes;
+using System.Buffers;
+using System.Text;
+
+public static class MessageBytes
+{
+    static MessageBytes()
+    {
+        var smallMessage = CreateMessage(1024); //1KB
+        SmallProtobufMessageBytes = new 
ReadOnlySequence<byte>(smallMessage.ToByteArray());
+        SmallJsonMessageBytes = new 
ReadOnlySequence<byte>(Encoding.UTF8.GetBytes(JsonFormatter.Default.Format(smallMessage)));
+
+        var largeMessage = CreateMessage(1024*1024); //1MB
+        LargeProtobufMessageBytes = new 
ReadOnlySequence<byte>(largeMessage.ToByteArray());
+        LargeJsonMessageBytes = new 
ReadOnlySequence<byte>(Encoding.UTF8.GetBytes(JsonFormatter.Default.Format(largeMessage)));
+    }
+
+    public static ReadOnlySequence<byte> SmallProtobufMessageBytes { get; }
+    public static ReadOnlySequence<byte> LargeProtobufMessageBytes { get; }
+    public static ReadOnlySequence<byte> SmallJsonMessageBytes { get; }
+    public static ReadOnlySequence<byte> LargeJsonMessageBytes { get; }
+
+    public static ReadOnlySequence<byte> GetBytes(MessageSize messageSize, 
MessageType messageType)
+    {
+        if (messageSize == MessageSize.Small && messageType == 
MessageType.Protobuf)
+            return SmallProtobufMessageBytes;
+        if (messageSize == MessageSize.Large && messageType == 
MessageType.Protobuf)
+            return LargeProtobufMessageBytes;
+        if (messageSize == MessageSize.Small && messageType == 
MessageType.Json)
+            return SmallJsonMessageBytes;
+        return LargeJsonMessageBytes;
+    }
+
+    private static Message CreateMessage(int minimumByteSize)
+    {
+        var message = new Message()
+        {
+            Pi = 3.14159265359,
+            IsTrue = true,
+            OneHour = TimeSpan.FromHours(1).ToDuration(),
+            Now = DateTime.UtcNow.ToTimestamp(),
+        };
+
+        while (message.CalculateSize() < minimumByteSize)
+        {
+            var innerMessage = new InnerMessage
+            {
+                MyEnum = InnerMessage.Types.Enum.Five,
+                NewGuid = Guid.NewGuid().ToString("N"),
+                RandomNumber = Random.Shared.Next()
+            };
+
+            message.InnerMessages.Add(innerMessage);
+        }
+
+        return message;
+    }
+}
diff --git a/benchmarks/Compression/MessageSize.cs 
b/benchmarks/Compression/MessageSize.cs
new file mode 100644
index 0000000..2f4d88f
--- /dev/null
+++ b/benchmarks/Compression/MessageSize.cs
@@ -0,0 +1,21 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Compression;
+
+public enum MessageSize
+{
+    Small = 0,
+    Large = 1
+}
diff --git a/benchmarks/Compression/MessageType.cs 
b/benchmarks/Compression/MessageType.cs
new file mode 100644
index 0000000..1919bad
--- /dev/null
+++ b/benchmarks/Compression/MessageType.cs
@@ -0,0 +1,21 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Compression;
+
+public enum MessageType
+{
+    Protobuf = 0,
+    Json = 1
+}
diff --git a/benchmarks/Compression/Messages.proto 
b/benchmarks/Compression/Messages.proto
new file mode 100644
index 0000000..95a2f69
--- /dev/null
+++ b/benchmarks/Compression/Messages.proto
@@ -0,0 +1,30 @@
+syntax = "proto3";
+
+option csharp_namespace = "Compression.Messages";
+
+package compression.Messages;
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+message Message {
+  double pi = 1;
+  bool is_true = 2;
+  google.protobuf.Duration one_hour = 3;
+  google.protobuf.Timestamp now = 4;
+  repeated InnerMessage inner_messages = 5;
+}
+
+message InnerMessage {
+  enum Enum {
+    ENUM_UNSPECIFIED = 0;
+    ENUM_ONE = 1;
+    ENUM_TWO = 2;
+    ENUM_THREE = 3;
+    ENUM_FOUR = 4;
+    ENUM_FIVE = 5;
+  }
+  Enum my_enum = 1;
+  int32 random_number = 2;
+  string new_guid = 3;
+}
diff --git a/benchmarks/Compression/Program.cs 
b/benchmarks/Compression/Program.cs
new file mode 100644
index 0000000..1b91426
--- /dev/null
+++ b/benchmarks/Compression/Program.cs
@@ -0,0 +1,40 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using BenchmarkDotNet.Running;
+using Compression;
+
+OutputCompressionInfo(MessageSize.Small, MessageType.Protobuf);
+OutputCompressionInfo(MessageSize.Large, MessageType.Protobuf);
+OutputCompressionInfo(MessageSize.Small, MessageType.Json);
+OutputCompressionInfo(MessageSize.Large, MessageType.Json);
+
+BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
+
+static void OutputCompressionInfo(MessageSize size, MessageType type)
+{
+    var data = MessageBytes.GetBytes(size, type);
+    Console.WriteLine($"{size} {type} message. Uncompressed size: 
{data.Length}");
+
+    using (var compressor = 
Factories.K4aosCompressionLz4CompressorFactory.Create())
+        Console.WriteLine($"\tCompressed with K4os.Compression.LZ4: 
{compressor.Compress(data).Length}");
+    using (var compressor = Factories.IronSnappyCompressorFactory.Create())
+        Console.WriteLine($"\tCompressed with IronSnappy: 
{compressor.Compress(data).Length}");
+    using (var compressor = Factories.DotNetZipCompressorFactory.Create())
+        Console.WriteLine($"\tCompressed with DotNetZip: 
{compressor.Compress(data).Length}");
+    using (var compressor = Factories.ZstdNetCompressorFactory.Create())
+        Console.WriteLine($"\tCompressed with ZstdNet: 
{compressor.Compress(data).Length}");
+    using (var compressor = Factories.ZstdSharpCompressorFactory.Create())
+        Console.WriteLine($"\tCompressed with ZstdSharp.Port: 
{compressor.Compress(data).Length}");
+}
diff --git a/tests/DotPulsar.Tests/DotPulsar.Tests.csproj 
b/tests/DotPulsar.Tests/DotPulsar.Tests.csproj
index ec8627e..e4e6e7e 100644
--- a/tests/DotPulsar.Tests/DotPulsar.Tests.csproj
+++ b/tests/DotPulsar.Tests/DotPulsar.Tests.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <TargetFramework>net8.0</TargetFramework>
@@ -36,7 +36,7 @@
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; 
buildtransitive</IncludeAssets>
     </PackageReference>
     <PackageReference Include="ZstdNet" Version="1.4.5" />
-    <PackageReference Include="ZstdSharp.Port" Version="0.7.4" />
+    <PackageReference Include="ZstdSharp.Port" Version="0.7.5" />
   </ItemGroup>
 
   <ItemGroup>

Reply via email to