UnitTests/SandbankBenchmarksTest.cs
using Sandbox;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using static TestClasses;
namespace SandbankDatabase;
[TestClass]
public partial class SandbankBenchmarksTest
{
[TestCleanup]
public void Cleanup()
{
Sandbank.DeleteAllData();
Sandbank.Shutdown().GetAwaiter().GetResult();
}
[TestInitialize]
public void Initialise()
{
InitialisationController.Initialise();
}
[TestMethod]
public void BenchmarkObfuscation()
{
var text = Obfuscation.ObfuscateFileText( "Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Garry Newman HATES bacon.... LOL!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!" +
"Wow! I love bacon! 豚肉が美味しい!"
);
for (int i = 0; i < 10000; i++ )
{
text = Obfuscation.ObfuscateFileText( text );
text = Obfuscation.UnobfuscateFileText( text );
}
}
[TestMethod]
public void BenchmarkInsertTest()
{
Sandbank.Insert( "players", new ReadmeExample() ); // Register the class type with the pool.
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
int documents = 100800;
ReadmeExample[] testData = new ReadmeExample[documents];
for ( int i = 0; i < documents; i++ )
{
testData[i] = new ReadmeExample()
{
Health = 100,
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
};
}
var watch = new Stopwatch();
watch.Start();
for ( int i = 0; i < documents; i++ )
{
Sandbank.Insert( "players", testData[i] );
}
watch.Stop();
Console.WriteLine( $"Benchmark: Insert() - {documents} documents inserted in {watch.Elapsed.TotalSeconds} seconds" );
}
[TestMethod]
public void BenchmarkLong()
{
Sandbank.Insert( "players", new ReadmeExample() ); // Register the class type with the pool.
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
// Benchmark for at least 30 seconds.
const int duration = 30;
const int documentsPerSecond = 20000;
const int totalDocuments = duration * documentsPerSecond;
ReadmeExample[] testData = new ReadmeExample[totalDocuments];
for ( int i = 0; i < totalDocuments; i++ )
{
testData[i] = new ReadmeExample()
{
Health = Game.Random.Int(1, 100),
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
};
}
int currentDocument = 0;
var watch = new Stopwatch();
watch.Start();
for (int i = 0; i < duration; i++ )
{
for ( int d = 0; d < documentsPerSecond; d++, currentDocument++ )
{
Sandbank.Insert( "players", testData[currentDocument] );
}
Task.Delay( 500 ).GetAwaiter().GetResult();
var data = Sandbank.Select<ReadmeExample>( "players", x => x.Health > 50 );
Task.Delay( 500 ).GetAwaiter().GetResult();
}
watch.Stop();
Console.WriteLine( $"Benchmark: Long() - completed in {watch.Elapsed.TotalSeconds} seconds" );
}
[TestMethod]
public void BenchmarkInsertThreaded()
{
Sandbank.Insert( "players", new ReadmeExample() ); // Register the class type with the pool.
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
int documents = 100800;
int threads = 24;
int documentsPerThread = documents / threads;
List<ReadmeExample> testData = new();
for ( int i = 0; i < documentsPerThread; i++ )
{
testData.Add( new ReadmeExample()
{
Health = 100,
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
} );
}
List<Task> tasks = new();
var watch = new Stopwatch();
watch.Start();
for ( int t = 0; t < threads; t++ )
{
tasks.Add( Task.Run( () =>
{
for ( int i = 0; i < documentsPerThread; i++ )
{
Sandbank.Insert<ReadmeExample>( "players", testData[i] );
}
} ) );
}
Task.WhenAll( tasks ).GetAwaiter().GetResult();
watch.Stop();
Console.WriteLine( $"Benchmark: [multi-threaded] Insert() - {documents} documents inserted in {watch.Elapsed.TotalSeconds} seconds" );
}
[TestMethod]
public void BenchmarkSelect()
{
int collectionSize = 100800;
for ( int i = 0; i < collectionSize; i++ )
{
Sandbank.Insert( "players", new ReadmeExample()
{
Health = Game.Random.Next( 101 ),
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
} );
}
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
var watch = new Stopwatch();
watch.Start();
Sandbank.Select<ReadmeExample>( "players", x => x.Health >= 90 );
watch.Stop();
Console.WriteLine( $"Benchmark: Select() - {collectionSize} documents searched in {watch.Elapsed.TotalSeconds} seconds" );
}
[TestMethod]
public void BenchmarkSelectThreaded()
{
int collectionSize = 100800;
int threads = 24;
for ( int i = 0; i < collectionSize; i++ )
{
Sandbank.Insert<ReadmeExample>( "players", new ReadmeExample()
{
Health = Game.Random.Next( 101 ),
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
} );
}
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
List<Task> tasks = new();
var watch = new Stopwatch();
watch.Start();
for ( int t = 0; t < threads; t++ )
{
tasks.Add( Task.Run( () =>
{
Sandbank.Select<ReadmeExample>( "players", x => x.Health >= 90 );
} ) );
}
Task.WhenAll( tasks ).GetAwaiter().GetResult();
watch.Stop();
Console.WriteLine( $"Benchmark: [multi-threaded] Select() - {collectionSize} documents searched {threads} times in {watch.Elapsed.TotalSeconds} seconds (~10,080 records returned)" );
}
// Same as BenchmarkSelectThreaded except with fewer returned records, making
// it a bit more realistic.
[TestMethod]
public void BenchmarkSelectThreadedFewerRecords()
{
int collectionSize = 100800;
int threads = 24;
for ( int i = 0; i < collectionSize; i++ )
{
Sandbank.Insert<ReadmeExample>( "players", new ReadmeExample()
{
Health = Game.Random.Next( 101 ),
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
} );
}
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
List<Task> tasks = new();
var watch = new Stopwatch();
watch.Start();
for ( int t = 0; t < threads; t++ )
{
tasks.Add( Task.Run( () =>
{
Sandbank.Select<ReadmeExample>( "players", x => x.Health == 100 );
} ) );
}
Task.WhenAll( tasks ).GetAwaiter().GetResult();
watch.Stop();
Console.WriteLine( $"Benchmark: [multi-threaded] Select() - {collectionSize} documents searched {threads} times in {watch.Elapsed.TotalSeconds} seconds (~1,080 records returned)" );
}
[TestMethod]
public void BenchmarkSelectUnsafeReferences()
{
int collectionSize = 100800;
for ( int i = 0; i < collectionSize; i++ )
{
Sandbank.Insert( "players", new ReadmeExample()
{
Health = Game.Random.Next( 101 ),
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
} );
}
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
var watch = new Stopwatch();
watch.Start();
Sandbank.SelectUnsafeReferences<ReadmeExample>( "players", x => x.Health >= 90 );
watch.Stop();
Console.WriteLine( $"Benchmark: SelectUnsafeReferences() - {collectionSize} documents searched in {watch.Elapsed.TotalSeconds} seconds (~10,080 records returned)" );
}
[TestMethod]
public void BenchmarkSelectUnsafeReferencesThreaded()
{
int collectionSize = 100800;
int threads = 24;
for ( int i = 0; i < collectionSize; i++ )
{
Sandbank.Insert<ReadmeExample>( "players", new ReadmeExample()
{
Health = Game.Random.Next( 101 ),
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
} );
}
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
List<Task> tasks = new();
var watch = new Stopwatch();
watch.Start();
for ( int t = 0; t < threads; t++ )
{
tasks.Add( Task.Run( () =>
{
Sandbank.SelectUnsafeReferences<ReadmeExample>( "players", x => x.Health >= 90 );
} ) );
}
Task.WhenAll( tasks ).GetAwaiter().GetResult();
watch.Stop();
Console.WriteLine( $"Benchmark: [multi-threaded] SelectUnsafeReferences() - {collectionSize} documents searched {threads} times in {watch.Elapsed.TotalSeconds} seconds (~10,080 records returned)" );
}
[TestMethod]
public void BenchmarkSelectUnsafeReferencesThreaded_MoreIntense()
{
int collectionSize = 1008000;
int threads = 24;
for ( int i = 0; i < collectionSize; i++ )
{
Sandbank.Insert<ReadmeExample>( "players", new ReadmeExample()
{
Health = Game.Random.Next( 101 ),
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
} );
}
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
List<Task> tasks = new();
var watch = new Stopwatch();
watch.Start();
for ( int t = 0; t < threads; t++ )
{
tasks.Add( Task.Run( () =>
{
Sandbank.SelectUnsafeReferences<ReadmeExample>( "players", x => x.Health >= 90 );
} ) );
}
Task.WhenAll( tasks ).GetAwaiter().GetResult();
watch.Stop();
Console.WriteLine( $"Benchmark: [multi-threaded] SelectUnsafeReferences_MoreIntense() - {collectionSize} documents searched {threads} times in {watch.Elapsed.TotalSeconds} seconds (~10,080 records returned)" );
}
[TestMethod]
public void BenchmarkSelectOneWithID()
{
int collectionSize = 100800;
string id = "";
int repeats = 100000;
for ( int i = 0; i < collectionSize; i++ )
{
var data = new ReadmeExample()
{
Health = Game.Random.Next( 101 ),
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
};
Sandbank.Insert( "players", data );
if ( i == collectionSize / 2 )
id = data.UID;
}
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
var watch = new Stopwatch();
watch.Start();
for ( int i = 0; i < repeats; i++ )
{
Sandbank.SelectOneWithID<ReadmeExample>( "players", id );
}
watch.Stop();
Console.WriteLine( $"Benchmark: SelectOneWithID() - {collectionSize} documents searched {repeats} times in {watch.Elapsed.TotalSeconds} seconds" );
}
[TestMethod]
public void BenchmarkSelectOneWithIDThreaded()
{
int collectionSize = 100800;
int repeats = 100000;
int threads = 24;
string id = "";
for ( int i = 0; i < collectionSize; i++ )
{
var data = new ReadmeExample()
{
Health = Game.Random.Next( 101 ),
Name = "TestPlayer1",
Level = 10,
LastPlayTime = DateTime.UtcNow,
Items = new() { "gun", "frog", "banana" }
};
Sandbank.Insert( "players", data );
if ( i == collectionSize / 2 )
id = data.UID;
}
List<Task> tasks = new();
Task.Delay( 4000 ).GetAwaiter().GetResult(); // Let the pool warm up.
var watch = new Stopwatch();
watch.Start();
for ( int t = 0; t < threads; t++ )
{
tasks.Add( Task.Run( () =>
{
for ( int i = 0; i < repeats; i++ )
{
Sandbank.SelectOneWithID<ReadmeExample>( "players", id );
}
} ) );
}
Task.WhenAll( tasks ).GetAwaiter().GetResult();
watch.Stop();
Console.WriteLine( $"Benchmark: [multi-threaded] SelectOneWithID() - {collectionSize} documents searched {repeats} times in {watch.Elapsed.TotalSeconds} seconds" );
}
}