From 22bda45ade0ec51baa2dae03111d16e9de342508 Mon Sep 17 00:00:00 2001 From: Loretta Date: Mon, 26 Jan 2026 10:23:43 +0100 Subject: [PATCH] Add string interning analysis and recent data filtering - Add using directives for binary and JSON serializers. - Reformat and clarify Hungarian documentation comments. - Add GetAnalyzeStringInternCandidatesLog test (DEBUG only) to analyze string interning opportunities in recent orders. - Filter OrderDtoToToon test data to only include orders and shippings from the last 70 days. - Improves test relevance and adds diagnostics for serialization efficiency. --- FruitBankHybrid.Shared.Tests/ToonTests.cs | 102 +++++++++++++--------- 1 file changed, 62 insertions(+), 40 deletions(-) diff --git a/FruitBankHybrid.Shared.Tests/ToonTests.cs b/FruitBankHybrid.Shared.Tests/ToonTests.cs index 136975dc..d9933107 100644 --- a/FruitBankHybrid.Shared.Tests/ToonTests.cs +++ b/FruitBankHybrid.Shared.Tests/ToonTests.cs @@ -1,6 +1,8 @@ using AyCode.Core.Enums; using AyCode.Core.Extensions; using AyCode.Core.Loggers; +using AyCode.Core.Serializers.Binaries; +using AyCode.Core.Serializers.Jsons; using AyCode.Core.Serializers.Toons; using FruitBank.Common; using FruitBank.Common.Dtos; @@ -14,67 +16,69 @@ using Nop.Core.Domain.Common; using Nop.Core.Domain.Orders; using Nop.Core.Domain.Payments; using System.Linq.Expressions; +using System.Runtime.InteropServices.JavaScript; using System.Runtime.Serialization; +using System.Text; namespace FruitBankHybrid.Shared.Tests; -1. "Headered List" (A biztonságos táblázatosítás) +//1. "Headered List" (A biztonságos táblázatosítás) -Az LLM-eknek nem kell minden sorban megismételni a mezőneveket, ha a lista elején egyszer definiálod a sorrendet. Ez nem találgatás, hanem egy lokális "szerződés". +//Az LLM-eknek nem kell minden sorban megismételni a mezőneveket, ha a lista elején egyszer definiálod a sorrendet. Ez nem találgatás, hanem egy lokális "szerződés". -Hagyományos (pazarló): -Kódrészlet +//Hagyományos (pazarló): +//Kódrészlet -OrderItemDtos = [ - OrderItemDto { Id = 120, Quantity = 10, ProductName = "Áfonya" } - OrderItemDto { Id = 121, Quantity = 5, ProductName = "Narancs" } -] +//OrderItemDtos = [ +// OrderItemDto { Id = 120, Quantity = 10, ProductName = "Áfonya" } +// OrderItemDto { Id = 121, Quantity = 5, ProductName = "Narancs" } +//] -Optimalizált (pontos és tömör): -Kódrészlet +//Optimalizált (pontos és tömör): +//Kódrészlet -OrderItemDtos: OrderItemDto[] = [ - [ Id, Quantity, ProductName ] - [ 120, 10, "Áfonya" ] - [ 121, 5, "Narancs" ] -] +//OrderItemDtos: OrderItemDto[] = [ +// [ Id, Quantity, ProductName ] +// [ 120, 10, "Áfonya" ] +// [ 121, 5, "Narancs" ] +//] - Miért jó ez? Az LLM a fejléc alapján (mint egy CSV-nél) rendeli hozzá az értékeket a típushoz. Mivel a típus (OrderItemDto) ott van a definícióban, a szemantikai kapcsolat nem vész el. +// Miért jó ez? Az LLM a fejléc alapján (mint egy CSV-nél) rendeli hozzá az értékeket a típushoz. Mivel a típus (OrderItemDto) ott van a definícióban, a szemantikai kapcsolat nem vész el. -2. Típus-öröklődés a listákban +//2. Típus-öröklődés a listákban -Ha a @types részben már leírtad, hogy az OrderItemDto.ProductDto mezője egy ProductDto típust vár, akkor a @data részben felesleges kiírni a típusnevet minden egyes elemnél. +//Ha a @types részben már leírtad, hogy az OrderItemDto.ProductDto mezője egy ProductDto típust vár, akkor a @data részben felesleges kiírni a típusnevet minden egyes elemnél. -Példa: -Kódrészlet +//Példa: +//Kódrészlet -// A 'ProductDto' elhagyható az objektum elől, mert a sémából tudja -ProductDto = { - Id = 1 - Name = "Áfonya..." - GenericAttributes = [ - { Id = 99, Key = "NetWeight", Value = "178.3" } - { Id = 100, Key = "GrossWeight", Value = "19" } - ] -} +//// A 'ProductDto' elhagyható az objektum elől, mert a sémából tudja +//ProductDto = { +// Id = 1 +// Name = "Áfonya..." +// GenericAttributes = [ +// { Id = 99, Key = "NetWeight", Value = "178.3" } +// { Id = 100, Key = "GrossWeight", Value = "19" } +// ] +//} -3. Alapértelmezett értékek elhagyása (Implicit Defaults) +//3. Alapértelmezett értékek elhagyása (Implicit Defaults) -Ha egy mező értéke megegyezik a @types-ban definiált default-value-val, vagy null/0/false, akkor azt teljesen hagyd ki a @data részből. +//Ha egy mező értéke megegyezik a @types-ban definiált default-value-val, vagy null/0/false, akkor azt teljesen hagyd ki a @data részből. - Szabály: Ami nincs ott, az az alapértelmezett. +// Szabály: Ami nincs ott, az az alapértelmezett. - Token megtakarítás: A FruitBank példádban a GenericAttributes = (count: 0) [] sorok rengeteg helyet foglalnak. Ha üres, egyszerűen ne küldd el a mezőt. +// Token megtakarítás: A FruitBank példádban a GenericAttributes = (count: 0) [] sorok rengeteg helyet foglalnak. Ha üres, egyszerűen ne küldd el a mezőt. -4. String Table helyett: "Object Anchoring" +//4. String Table helyett: "Object Anchoring" -használd az objektum-referenciákat (amit a @ProductDto:1 jelöléssel már el is kezdett a rendszered). +//használd az objektum-referenciákat (amit a @ProductDto:1 jelöléssel már el is kezdett a rendszered). -Ha ugyanaz a Product szerepel 5 különböző rendelési tételnél, ne írd le ötször. +//Ha ugyanaz a Product szerepel 5 különböző rendelési tételnél, ne írd le ötször. - Első alkalommal: ProductDto { ... } +// Első alkalommal: ProductDto { ... } - Minden további alkalommal: ProductDto = @ProductDto:1 +// Minden további alkalommal: ProductDto = @ProductDto:1 //[ToonIgnore][ToonDataIgnore] [ToonDescription(Purpose = "Container model for Shipping, Order")] @@ -103,13 +107,31 @@ public sealed class ToonTests }); } +#if DEBUG + [TestMethod] + public async Task GetAnalyzeStringInternCandidatesLog() + { + var orders = (await _signalRClient.GetAllOrderDtos())!.Where(x=>x.CreatedOnUtc > DateTime.UtcNow.AddDays(-70)).ToList(); + + var options = AcBinarySerializerOptions.WithoutReferenceHandling; + //options.SetReferenceHandlingUnsafe(ReferenceHandlingMode.OnlyId); + var analysisLog = AcBinarySerializer.GetAnalyzeStringInternCandidatesLog(orders, options); + + Assert.IsNotNull(analysisLog); + Assert.IsGreaterThan(0, analysisLog.Length); + + // Print results sorted by occurrence count + Console.WriteLine(analysisLog.ToString()); + Console.WriteLine(); + } +#endif [TestMethod] public async Task OrderDtoToToon() { var a = new FullProcessModel(); - a.Orders = (await _signalRClient.GetAllOrderDtos())!; - a.Shippings = (await _signalRClient.GetShippings())!; + a.Orders = (await _signalRClient.GetAllOrderDtos())!.Where(x=>x.CreatedOnUtc > DateTime.UtcNow.AddDays(-70)).ToList(); + a.Shippings = (await _signalRClient.GetShippings())!.Where(x=>x.Created > DateTime.UtcNow.AddDays(-70)).ToList(); var toon = AcToonSerializer.Serialize(a, FruitBankConstClient.DomainDescription, AcToonSerializerOptions.Default);