Skip to content

Commit

Permalink
speed up for xor
Browse files Browse the repository at this point in the history
  • Loading branch information
Folleach committed Nov 1, 2023
1 parent 36ec66a commit b92f703
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 2 deletions.
30 changes: 30 additions & 0 deletions GeometryDashAPI.Benchmarks/Benchmarks/XorBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Linq;
using BenchmarkDotNet.Attributes;

namespace GeometryDashAPI.Benchmarks.Benchmarks;

[MemoryDiagnoser]
public class XorBenchmark
{
private static Random random = new(123);
private byte[] array = Enumerable.Range(0, 1000).Select(x => (byte)random.Next(byte.MaxValue)).ToArray();

[Benchmark]
public void SimdXor()
{
Crypt.InlineXor(array, 11);
}

[Benchmark]
public void NaiveXor()
{
Crypt.NaiveXor(array, 11);
}

[Benchmark]
public byte[] OldXor()
{
return Crypt.XOR(array, 11);
}
}
23 changes: 23 additions & 0 deletions GeometryDashAPI.Tests/CryptTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;

namespace GeometryDashAPI.Tests;

[TestFixture]
public class CryptTests
{
[Test]
public void InlineXor()
{
var random = new Random(123);
var data = Enumerable.Range(0, 100).Select(_ => (byte)random.Next(byte.MaxValue)).ToArray();
var expected = (byte[])data.Clone();

Crypt.NaiveXor(expected, 11);
Crypt.InlineXor(data.AsSpan(), 11);

data.Should().BeEquivalentTo(expected);
}
}
23 changes: 22 additions & 1 deletion GeometryDashAPI/Crypt.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Numerics;
using System.Text;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

Expand All @@ -16,12 +17,32 @@ public static byte[] XOR(byte[] data, int key)
return result;
}

public static void InlineXor(Span<byte> data, int key)
public static void NaiveXor(Span<byte> data, byte key)
{
for (var i = 0; i < data.Length; i++)
data[i] = (byte)(data[i] ^ key);
}

public static void InlineXor(Span<byte> data, byte key)
{
#if NET6_0_OR_GREATER
var startIndex = 0;
var vKey = new Vector<byte>(key);
while (startIndex + Vector<byte>.Count < data.Length)
{
var vData = new Vector<byte>(data.Slice(startIndex));
var r = Vector.Xor(vData, vKey);
r.CopyTo(data.Slice(startIndex));
startIndex += Vector<byte>.Count;
}

for (var i = startIndex; i < data.Length; i++)
data[i] = (byte)(data[i] ^ key);
#else
NaiveXor(data, key);
#endif
}

public static string XOR(string text, string key)
{
var result = new StringBuilder();
Expand Down
2 changes: 1 addition & 1 deletion GeometryDashAPI/GeometryDashAPI.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks>
<TargetFrameworks>netstandard2.1;netstandard2.0;net6.0</TargetFrameworks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>Folleach</Authors>
<NeutralLanguage>en</NeutralLanguage>
Expand Down

0 comments on commit b92f703

Please sign in to comment.