Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order;
using Foundation.Data.Doublets.Cli.Benchmarks.Models;
using Foundation.Data.Doublets.Cli.Benchmarks.Services;
using Foundation.Data.Doublets.Cli.Benchmarks.Serialization;
using System.Text;
using System.Text.Json;

namespace Foundation.Data.Doublets.Cli.Benchmarks.Benchmarks;

[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
public class TransportProtocolBenchmarks
{
private LinksService _linksService = null!;
private LinkData _testLink = null!;
private CreateLinkRequest _createRequest = null!;
private QueryLinksRequest _queryRequest = null!;

private string _linoSerialized = null!;
private string _jsonSerialized = null!;

[GlobalSetup]
public void Setup()
{
_linksService = new LinksService("benchmark.links");

// Create test data
_createRequest = new CreateLinkRequest { Source = 1, Target = 2 };
_testLink = new LinkData { Id = 1, Source = 1, Target = 2 };
_queryRequest = new QueryLinksRequest { Id = 1 };

// Pre-serialize data for serialization benchmarks
_linoSerialized = LinoSerializer.SerializeLinkData(_testLink);
_jsonSerialized = JsonSerializer.Serialize(_testLink);

Console.WriteLine($"LINO serialized: {_linoSerialized}");
Console.WriteLine($"JSON serialized: {_jsonSerialized}");
}

[GlobalCleanup]
public void Cleanup()
{
_linksService?.Dispose();

// Clean up database files
if (File.Exists("benchmark.links"))
File.Delete("benchmark.links");
if (File.Exists("benchmark.names.links"))
File.Delete("benchmark.names.links");
}

#region Serialization Benchmarks

[Benchmark(Description = "LINO Serialization")]
public string LinoSerialization()
{
return LinoSerializer.SerializeLinkData(_testLink);
}

[Benchmark(Description = "JSON Serialization")]
public string JsonSerialization()
{
return JsonSerializer.Serialize(_testLink);
}

[Benchmark(Description = "LINO Deserialization")]
public LinkData? LinoDeserialization()
{
return LinoSerializer.DeserializeLinkData(_linoSerialized);
}

[Benchmark(Description = "JSON Deserialization")]
public LinkData? JsonDeserialization()
{
return JsonSerializer.Deserialize<LinkData>(_jsonSerialized);
}

#endregion

#region Data Operations Benchmarks

[Benchmark(Description = "Create Link")]
public async Task<LinkData> CreateLink()
{
var request = new CreateLinkRequest { Source = (uint)Random.Shared.Next(1000, 9999), Target = (uint)Random.Shared.Next(1000, 9999) };
return await _linksService.CreateLinkAsync(request);
}

[Benchmark(Description = "Query Links")]
public async Task<List<LinkData>> QueryLinks()
{
var request = new QueryLinksRequest { Source = 1 };
var results = await _linksService.QueryLinksAsync(request);
return results.ToList();
}

#endregion

#region Protocol Simulation Benchmarks

[Benchmark(Description = "REST-like LINO Processing")]
public string RestLikeProcessing()
{
// Simulate REST API processing with LINO serialization
var createRequestLino = LinoSerializer.SerializeCreateRequest(_createRequest);
var parsed = ParseCreateRequestLino(createRequestLino);
return LinoSerializer.SerializeLinkData(new LinkData { Id = 999, Source = parsed.Source, Target = parsed.Target });
}

[Benchmark(Description = "gRPC-like LINO Processing")]
public string GrpcLikeProcessing()
{
// Simulate gRPC processing with LINO in message wrapper
var wrapper = new { lino_data = LinoSerializer.SerializeLinkData(_testLink) };
var serialized = JsonSerializer.Serialize(wrapper);
var deserialized = JsonSerializer.Deserialize<dynamic>(serialized);
return deserialized?.lino_data ?? "";
}

[Benchmark(Description = "GraphQL-like LINO Processing")]
public string GraphqlLikeProcessing()
{
// Simulate GraphQL query resolution with LINO
var query = $"query {{ link(id: {_testLink.Id}) {{ id source target }} }}";
var result = LinoSerializer.SerializeLinkData(_testLink);
return $"{{ \"data\": {{ \"link\": \"{result}\" }} }}";
}

#endregion

private CreateLinkRequest ParseCreateRequestLino(string linoString)
{
// Simple parser for LINO create format: () ((source target))
var parts = linoString.Replace("()", "").Replace("((", "").Replace("))", "").Trim().Split(' ');
return new CreateLinkRequest
{
Source = uint.Parse(parts[0]),
Target = uint.Parse(parts[1])
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ο»Ώ<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Grpc.AspNetCore" Version="2.66.0" />
<PackageReference Include="HotChocolate.AspNetCore" Version="13.9.12" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="Platform.Protocols.Lino" Version="0.4.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Foundation.Data.Doublets.Cli\Foundation.Data.Doublets.Cli.csproj" />
</ItemGroup>

<ItemGroup>
<Protobuf Include="Protocols\Grpc\links.proto" GrpcServices="Both" />
</ItemGroup>

</Project>
44 changes: 44 additions & 0 deletions Foundation.Data.Doublets.Cli.Benchmarks/Models/LinkData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.ComponentModel.DataAnnotations;

namespace Foundation.Data.Doublets.Cli.Benchmarks.Models;

public class LinkData
{
public uint Id { get; set; }
public uint Source { get; set; }
public uint Target { get; set; }
}

public class CreateLinkRequest
{
[Required]
public uint Source { get; set; }

[Required]
public uint Target { get; set; }
}

public class UpdateLinkRequest
{
[Required]
public uint Id { get; set; }

[Required]
public uint Source { get; set; }

[Required]
public uint Target { get; set; }
}

public class DeleteLinkRequest
{
[Required]
public uint Id { get; set; }
}

public class QueryLinksRequest
{
public uint? Id { get; set; }
public uint? Source { get; set; }
public uint? Target { get; set; }
}
9 changes: 9 additions & 0 deletions Foundation.Data.Doublets.Cli.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Foundation.Data.Doublets.Cli.Benchmarks;

public class Program
{
public static async Task Main(string[] args)
{
await SimpleBenchmark.RunBenchmarksAsync();
}
}
53 changes: 53 additions & 0 deletions Foundation.Data.Doublets.Cli.Benchmarks/Protocols/Grpc/links.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
syntax = "proto3";

option csharp_namespace = "Foundation.Data.Doublets.Cli.Benchmarks.Protocols.Grpc";

package links;

service LinksService {
rpc CreateLink (CreateLinkRequest) returns (CreateLinkResponse);
rpc GetLink (GetLinkRequest) returns (GetLinkResponse);
rpc QueryLinks (QueryLinksRequest) returns (QueryLinksResponse);
rpc UpdateLink (UpdateLinkRequest) returns (UpdateLinkResponse);
rpc DeleteLink (DeleteLinkRequest) returns (DeleteLinkResponse);
}

message CreateLinkRequest {
string lino_data = 1;
}

message CreateLinkResponse {
string lino_data = 1;
}

message GetLinkRequest {
uint32 id = 1;
}

message GetLinkResponse {
string lino_data = 1;
}

message QueryLinksRequest {
string lino_query = 1;
}

message QueryLinksResponse {
string lino_data = 1;
}

message UpdateLinkRequest {
string lino_data = 1;
}

message UpdateLinkResponse {
string lino_data = 1;
}

message DeleteLinkRequest {
string lino_data = 1;
}

message DeleteLinkResponse {
bool success = 1;
}
Loading