Skip to content

Commit

Permalink
Updating readme with newer competitive benchmark results, updating Be…
Browse files Browse the repository at this point in the history
…nchmarks, bumping version number, ReleaseNotes, including docs in nuget package.

Remove old Fastenshtein versions from competitive benchmark

Updating Benchmarks

Altering message

Project file upgrades, fixing License link, including docs, version bump
  • Loading branch information
DanHarltey committed Jun 18, 2024
1 parent 0d930bd commit 9e564d2
Show file tree
Hide file tree
Showing 12 changed files with 433 additions and 541 deletions.
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ Fastenshtein is an optimized and fully unit tested Levenshtein implementation. I

From the included brenchmarking tests comparing random words of 3 to 20 random chars to other Nuget Levenshtein implementations.

| Method | Mean | StdDev | Scaled | Scaled-StdDev | Gen 0 | Allocated |
|---------------------- |------------ |---------- |------- |-------------- |---------- |---------- |
| Fastenshtein | 16.2006 ms | 0.0069 ms | 1.00 | 0.00 | - | 20.48 kB |
| FastenshteinStatic | 17.2029 ms | 0.0234 ms | 1.06 | 0.00 | - | 2.81 MB |
| StringSimilarity | 24.1955 ms | 0.0280 ms | 1.49 | 0.00 | 329.1667 | 5.87 MB |
| NinjaNye | 35.9226 ms | 0.0152 ms | 2.22 | 0.00 | 6337.5000 | 44.21 MB |
| TNXStringManipulation | 45.4600 ms | 0.0065 ms | 2.81 | 0.00 | 3329.1667 | 24.63 MB |
| MinimumEditDistance | 207.9967 ms | 0.0893 ms | 12.84 | 0.01 | 3404.1667 | 25.59 MB |
| Method | Mean | Ratio | Rank | Gen0 | Allocated | Alloc Ratio |
|------------------------ |---------:|------:|-----:|---------:|-----------:|------------:|
| Fastenshtein | 1.077 ms | 1.00 | 1 | - | 6345 B | 1.000 |
| FastenshteinStatic | 1.122 ms | 1.04 | 2 | 3.9063 | 265441 B | 41.835 |
| NinjaNye | 1.899 ms | 1.76 | 4 | 76.1719 | 4274593 B | 673.695 |
| StringSimilarity | 2.899 ms | 2.69 | 5 | 7.8125 | 543770 B | 85.701 |
| FuzzyStringsNetStandard | 7.351 ms | 6.81 | 6 | 414.0625 | 22967283 B | 3,619.745 |

## Usage

Expand Down
91 changes: 45 additions & 46 deletions benchmarks/Fastenshtein.Benchmarking/Benchmarks.cs
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
namespace Fastenshtein.Benchmarking
{
public class BenchmarkSmallWordsSingleThread : FastenshteinBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(90, 5);
}

public class BenchmarkNormalWordsSingleThread : FastenshteinBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(60, 20);
}

public class BenchmarkLargeWordsSingleThread : FastenshteinBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(10, 400);
}

public class CompetitiveBenchmarkSmallWordsSingleThread : CompetitiveSingleThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(90, 5);
}

public class CompetitiveBenchmarkNormalWordsSingleThread : CompetitiveSingleThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(60, 20);
}

public class CompetitiveBenchmarkLargeWordsSingleThread : CompetitiveSingleThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(20, 400);
}

public class CompetitiveBenchmarkSmallWordsMultiThread : CompetitiveMultiThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(100, 5);
}

public class CompetitiveBenchmarkNormalWordsMultiThread : CompetitiveMultiThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(90, 20);
}

public class CompetitiveBenchmarkLargeWordsMultiThread : CompetitiveMultiThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(50, 400);
}
namespace Fastenshtein.Benchmarking;

public class BenchmarkSmallWordsSingleThread : FastenshteinBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(90, 5);
}

public class BenchmarkNormalWordsSingleThread : FastenshteinBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(60, 20);
}

public class BenchmarkLargeWordsSingleThread : FastenshteinBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(10, 400);
}

public class CompetitiveBenchmarkSmallWordsSingleThread : CompetitiveSingleThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(90, 5);
}

public class CompetitiveBenchmarkNormalWordsSingleThread : CompetitiveSingleThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(60, 20);
}

public class CompetitiveBenchmarkLargeWordsSingleThread : CompetitiveSingleThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(20, 400);
}

public class CompetitiveBenchmarkSmallWordsMultiThread : CompetitiveMultiThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(100, 5);
}

public class CompetitiveBenchmarkNormalWordsMultiThread : CompetitiveMultiThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(90, 20);
}

public class CompetitiveBenchmarkLargeWordsMultiThread : CompetitiveMultiThreadBenchmark
{
protected override string[] CreateTestData() => RandomWords.Create(50, 400);
}
185 changes: 81 additions & 104 deletions benchmarks/Fastenshtein.Benchmarking/CompetitiveMultiThreadBenchmark.cs
Original file line number Diff line number Diff line change
@@ -1,128 +1,105 @@
namespace Fastenshtein.Benchmarking
{
using BenchmarkDotNet.Attributes;
using System.Threading.Tasks;
namespace Fastenshtein.Benchmarking;

[RankColumn]
public abstract class CompetitiveMultiThreadBenchmark
{
protected string[] words;
using BenchmarkDotNet.Attributes;
using System.Threading.Tasks;

protected abstract string[] CreateTestData();
[RankColumn]
public abstract class CompetitiveMultiThreadBenchmark
{
private string[] _words;

[GlobalSetup]
public void SetUp()
{
this.words = this.CreateTestData();
}
protected abstract string[] CreateTestData();

/*
* To add your own Levenshtein to the benchmarking alter the below code.
* Replace YourLevenshtein with your method.
*/
////[Benchmark]
////public void YourLevenshtein()
////{
//// Parallel.For(0, words.Length, i =>
//// {
//// for (int j = 0; j < words.Length; j++)
//// {
//// YourLevenshtein(words[i], words[j]);
//// }
//// });
////}
[GlobalSetup]
public void SetUp()
=> _words = CreateTestData();

[Benchmark]
public void Fastenshtein()
{
Parallel.For(0, words.Length, i =>
{
var levenshtein = new global::Fastenshtein.Levenshtein(words[i]);
/*
* To add your own Levenshtein to the benchmarking alter the below code.
* Replace YourLevenshtein with your method.
*/
////[Benchmark]
////public void YourLevenshtein()
////{
//// var words = _words;
//// Parallel.For(0, words.Length, i =>
//// {
//// for (int j = 0; j < words.Length; j++)
//// {
//// YourLevenshtein(words[i], words[j]);
//// }
//// });
////}

for (int j = 0; j < words.Length; j++)
{
levenshtein.DistanceFrom(words[j]);
}
});
}

[Benchmark]
public void FastenshteinStatic()
[Benchmark(Baseline = true)]
public void Fastenshtein()
{
var words = _words;
Parallel.For(0, words.Length, i =>
{
Parallel.For(0, words.Length, i =>
{
for (int j = 0; j < words.Length; j++)
{
global::Fastenshtein.Levenshtein.Distance(words[i], words[j]);
}
});
}
var levenshtein = new global::Fastenshtein.Levenshtein(words[i]);
[Benchmark(Baseline = true)]
public void Fastenshtein_1_0_0_8()
{
Parallel.For(0, words.Length, i =>
for (int j = 0; j < words.Length; j++)
{
var levenshtein = new global::Fastenshtein.Benchmarking.FastenshteinOld.Fastenshtein_1_0_0_8(words[i]);
for (int j = 0; j < words.Length; j++)
{
levenshtein.DistanceFrom(words[j]);
}
});
}
levenshtein.DistanceFrom(words[j]);
}
});
}

[Benchmark]
public void FastenshteinStatic_1_0_0_8()
[Benchmark]
public void FastenshteinStatic()
{
var words = _words;
Parallel.For(0, words.Length, i =>
{
Parallel.For(0, words.Length, i =>
for (int j = 0; j < words.Length; j++)
{
for (int j = 0; j < words.Length; j++)
{
global::Fastenshtein.Benchmarking.FastenshteinOld.Fastenshtein_1_0_0_8.Distance(words[i], words[j]);
}
});
}
global::Fastenshtein.Levenshtein.Distance(words[i], words[j]);
}
});
}

[Benchmark]
public void StringSimilarity()
{
// I've read the source code it is thread safe
var lev = new global::F23.StringSimilarity.Levenshtein();
[Benchmark]
public void StringSimilarity()
{
// I've read the source code it is thread safe
var lev = new global::F23.StringSimilarity.Levenshtein();

Parallel.For(0, words.Length, i =>
var words = _words;
Parallel.For(0, words.Length, i =>
{
for (int j = 0; j < words.Length; j++)
{
for (int j = 0; j < words.Length; j++)
{
// why does it return a double ??
lev.Distance(words[i], words[j]);
}
});
}
// why does it return a double ??
lev.Distance(words[i], words[j]);
}
});
}

[Benchmark]
public void NinjaNye()
[Benchmark]
public void NinjaNye()
{
var words = _words;
Parallel.For(0, words.Length, i =>
{
Parallel.For(0, words.Length, i =>
for (int j = 0; j < words.Length; j++)
{
for (int j = 0; j < words.Length; j++)
{
global::NinjaNye.SearchExtensions.Levenshtein.LevenshteinProcessor.LevenshteinDistance(words[i], words[j]);
}
});
}
global::NinjaNye.SearchExtensions.Levenshtein.LevenshteinProcessor.LevenshteinDistance(words[i], words[j]);
}
});
}


[Benchmark]
public void FuzzyStringsNetStandard()
[Benchmark]
public void FuzzyStringsNetStandard()
{
var words = _words;
Parallel.For(0, words.Length, i =>
{
Parallel.For(0, words.Length, i =>
for (int j = 0; j < words.Length; j++)
{
for (int j = 0; j < words.Length; j++)
{
global::DuoVia.FuzzyStrings.LevenshteinDistanceExtensions.LevenshteinDistance(words[i], words[j], true);
}
});
}
global::DuoVia.FuzzyStrings.LevenshteinDistanceExtensions.LevenshteinDistance(words[i], words[j], true);
}
});
}
}
Loading

0 comments on commit 9e564d2

Please sign in to comment.