using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; using UnityEngine; using Newtonsoft.Json; /// /// Utility script to compare the old JSON system vs new UDP binary system /// Attach this to any GameObject and check the console for size comparisons /// public class AvatarSyncComparison : MonoBehaviour { [Header("Comparison Settings")] [SerializeField] private bool runComparisonOnStart = true; [SerializeField] private bool showDetailedBreakdown = true; [SerializeField] private bool saveToFile = true; [SerializeField] private string outputFileName = "avatar_sync_comparison.txt"; [Header("Test Data - Avatar Reference")] [SerializeField] private Transform testAvatar; [SerializeField] private UDPAvatarBroadcaster udpBroadcaster; // Get actual settings [SerializeField] private UDPAvatarReceiver udpReceiver; // Get actual settings [Header("System Parameters")] [SerializeField] private float updateRate = 30f; // Hz - configurable refresh rate [SerializeField] private int oldSystemBoneCount = 80; // Calculated from avatar if available [SerializeField] private int oldSystemMeshCount = 4; // Calculated from avatar if available [SerializeField] private int oldSystemBlendShapesPerMesh = 52; // Calculated from avatar if available [Header("Code Complexity (Lines of Code)")] [SerializeField] private int oldSystemTotalLines = 2300; // Can be calculated by scanning files [SerializeField] private int newSystemTotalLines = 800; // Can be calculated by scanning files void Start() { if (runComparisonOnStart) { // Add 5 second delay to allow UDPAvatarBroadcaster to fully initialize Invoke(nameof(DelayedStart), 5f); } } void DelayedStart() { // Auto-calculate values from avatar if available CalculateAvatarParameters(); RunComparison(); } void CalculateAvatarParameters() { // Get UDPAvatarBroadcaster from same GameObject if not assigned if (udpBroadcaster == null) { udpBroadcaster = GetComponent(); } // Get actual values from UDP broadcaster if (udpBroadcaster != null) { updateRate = GetUDPBroadcasterUpdateRate(); Debug.Log($"Got actual update rate from UDPAvatarBroadcaster: {updateRate} Hz"); // Use the avatar from the broadcaster if not set if (testAvatar == null) { testAvatar = GetUDPBroadcasterAvatarRoot(); } } if (testAvatar != null) { // Calculate actual bone count from avatar SkinnedMeshRenderer[] meshRenderers = testAvatar.GetComponentsInChildren(); HashSet uniqueBones = new HashSet(); foreach (SkinnedMeshRenderer smr in meshRenderers) { if (smr.bones != null) { foreach (Transform bone in smr.bones) { if (bone != null) { uniqueBones.Add(bone); } } } } if (uniqueBones.Count > 0) { oldSystemBoneCount = uniqueBones.Count; } // Calculate actual mesh and blend shape counts if (meshRenderers.Length > 0) { oldSystemMeshCount = meshRenderers.Length; // Calculate average blend shapes per mesh int totalBlendShapes = 0; int meshesWithBlendShapes = 0; foreach (var mesh in meshRenderers) { if (mesh.sharedMesh != null && mesh.sharedMesh.blendShapeCount > 0) { totalBlendShapes += mesh.sharedMesh.blendShapeCount; meshesWithBlendShapes++; } } if (meshesWithBlendShapes > 0) { oldSystemBlendShapesPerMesh = totalBlendShapes / meshesWithBlendShapes; } } } Debug.Log($"Calculated Parameters: {oldSystemBoneCount} bones, {oldSystemMeshCount} meshes, {oldSystemBlendShapesPerMesh} blend shapes/mesh, {updateRate} Hz"); } float GetUDPBroadcasterUpdateRate() { if (udpBroadcaster == null) return updateRate; // Use reflection to get the private updateRate field var field = typeof(UDPAvatarBroadcaster).GetField("updateRate", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (field != null) { return (float)field.GetValue(udpBroadcaster); } return updateRate; // Fallback to current value } Transform GetUDPBroadcasterAvatarRoot() { if (udpBroadcaster == null) return null; // Use reflection to get the private avatarRoot field var field = typeof(UDPAvatarBroadcaster).GetField("avatarRoot", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (field != null) { return (Transform)field.GetValue(udpBroadcaster); } return null; } bool GetUDPBroadcasterFullDataMode() { if (udpBroadcaster == null) return false; // Use reflection to get the private fullDataMode field var field = typeof(UDPAvatarBroadcaster).GetField("fullDataMode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (field != null) { return (bool)field.GetValue(udpBroadcaster); } return false; } int GetUDPBroadcasterCurrentBoneCount() { if (udpBroadcaster == null) return 20; // Use reflection to get the private currentBoneCount field var field = typeof(UDPAvatarBroadcaster).GetField("currentBoneCount", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (field != null) { return (int)field.GetValue(udpBroadcaster); } return 20; // Default optimized mode } int GetUDPBroadcasterCurrentBlendShapeCount() { if (udpBroadcaster == null) return 10; // Use reflection to get the private currentBlendShapeCount field var field = typeof(UDPAvatarBroadcaster).GetField("currentBlendShapeCount", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (field != null) { return (int)field.GetValue(udpBroadcaster); } return 10; // Default optimized mode } [ContextMenu("Run Size Comparison")] public void RunComparison() { Debug.Log("=== Avatar Sync System Comparison ==="); // Simulate old JSON system var jsonSize = CalculateJSONSystemSize(); // Simulate new UDP binary system var binarySize = CalculateUDPBinarySize(); // Calculate efficiency gains float compressionRatio = (float)jsonSize / binarySize; float bandwidthReduction = (1f - (float)binarySize / jsonSize) * 100f; Debug.Log($"\nšŸ“Š SIZE COMPARISON:"); Debug.Log($"Old JSON System: {jsonSize:N0} bytes ({jsonSize / 1024f:F1} KB)"); Debug.Log($"New UDP Binary: {binarySize:N0} bytes ({binarySize / 1024f:F1} KB)"); Debug.Log($"Compression Ratio: {compressionRatio:F1}x smaller"); Debug.Log($"Bandwidth Reduction: {bandwidthReduction:F1}%"); if (showDetailedBreakdown) { ShowDetailedBreakdown(); } ShowNetworkImpact(jsonSize, binarySize); ShowSystemComplexity(); if (saveToFile) { SaveComparisonToFile(jsonSize, binarySize); } } int CalculateJSONSystemSize() { // Recreate the old AvatarSyncData structure using calculated values var oldSystemData = new { rootTransform = new { worldPosition = new { x = 0f, y = 0f, z = 0f }, worldRotation = new { x = 0f, y = 0f, z = 0f, w = 1f }, localScale = new { x = 1f, y = 1f, z = 1f } }, bones = GenerateOldSystemBones(oldSystemBoneCount), blendShapes = GenerateOldSystemBlendShapes(oldSystemMeshCount, oldSystemBlendShapesPerMesh), timestamp = Time.time }; string json = JsonConvert.SerializeObject(oldSystemData, Formatting.Indented); int jsonBytes = Encoding.UTF8.GetByteCount(json); Debug.Log($"šŸ“„ Old System Structure: {oldSystemBoneCount} bones, {oldSystemMeshCount} meshes Ɨ {oldSystemBlendShapesPerMesh} blend shapes = {oldSystemMeshCount * oldSystemBlendShapesPerMesh} total blend shapes"); Debug.Log($"šŸ“„ Sample JSON (first 200 chars):\n{json.Substring(0, Math.Min(200, json.Length))}..."); return jsonBytes; } int CalculateUDPBinarySize() { // Get actual bone and blend shape counts from UDP system int actualBoneCount = GetNewSystemBoneCount(); int actualBlendShapeCount = GetNewSystemBlendShapeCount(); // Calculate new UDP binary system size int headerSize = 1 + 4 + 4 + 1; // playerID + sequenceNumber + timestamp + isFullDataMode int rootTransformSize = (3 + 4 + 3) * 4; // 3 Vector3s + 1 Quaternion * 4 bytes per float int bonesSize = 4 + (actualBoneCount * (3 + 4) * 4); // bone count + bones * (position + rotation) * 4 bytes per float int blendShapesSize = 4 + (actualBlendShapeCount * 4); // blend shape count + weights * 4 bytes per float int totalSize = headerSize + rootTransformSize + bonesSize + blendShapesSize; Debug.Log($"šŸ”¢ New UDP Binary Structure:"); Debug.Log($" Header: {headerSize} bytes"); Debug.Log($" Root Transform: {rootTransformSize} bytes"); Debug.Log($" Bones ({actualBoneCount}): {bonesSize} bytes"); Debug.Log($" Blend Shapes ({actualBlendShapeCount}): {blendShapesSize} bytes"); Debug.Log($" Total: {totalSize} bytes"); return totalSize; } int GetNewSystemBoneCount() { // Get actual bone count from UDP broadcaster if (udpBroadcaster != null) { int actualBoneCount = GetUDPBroadcasterCurrentBoneCount(); bool fullDataMode = GetUDPBroadcasterFullDataMode(); if (showDetailedBreakdown) { string mode = fullDataMode ? "FULL DATA" : "OPTIMIZED"; Debug.Log($"UDP Broadcaster is in {mode} mode with {actualBoneCount} bones"); } return actualBoneCount; } // Default to optimized mode bone count return 20; } int GetNewSystemBlendShapeCount() { // Get actual blend shape count from UDP broadcaster if (udpBroadcaster != null) { int actualBlendShapeCount = GetUDPBroadcasterCurrentBlendShapeCount(); bool fullDataMode = GetUDPBroadcasterFullDataMode(); if (showDetailedBreakdown) { string mode = fullDataMode ? "FULL DATA" : "OPTIMIZED"; Debug.Log($"UDP Broadcaster is in {mode} mode with {actualBlendShapeCount} blend shapes"); } return actualBlendShapeCount; } // Default to optimized mode blend shape count return 10; } object[] GenerateOldSystemBones(int count) { object[] bones = new object[count]; string[] boneNames = { "Hips", "Spine", "Spine1", "Spine2", "Neck", "Head", "HeadTop_End", "LeftEye", "RightEye", "LeftShoulder", "LeftArm", "LeftArmTwist", "LeftForeArm", "LeftForeArmTwist", "LeftHand", "LeftHandThumb1", "LeftHandThumb2", "LeftHandThumb3", "LeftHandThumb4", "LeftHandIndex0", "LeftHandIndex1", "LeftHandIndex2", "LeftHandIndex3", "LeftHandIndex4", "LeftHandMiddle0", "LeftHandMiddle1", "LeftHandMiddle2", "LeftHandMiddle3", "LeftHandMiddle4", "LeftHandRing0", "LeftHandRing1", "LeftHandRing2", "LeftHandRing3", "LeftHandRing4", "LeftHandPinky0", "LeftHandPinky1", "LeftHandPinky2", "LeftHandPinky3", "LeftHandPinky4", "LeftPalm", "RightShoulder", "RightArm", "RightArmTwist", "RightForeArm", "RightForeArmTwist", "RightHand", "RightHandThumb1", "RightHandThumb2", "RightHandThumb3", "RightHandThumb4", "RightHandIndex0", "RightHandIndex1", "RightHandIndex2", "RightHandIndex3", "RightHandIndex4", "RightHandMiddle0", "RightHandMiddle1", "RightHandMiddle2", "RightHandMiddle3", "RightHandMiddle4", "RightHandRing0", "RightHandRing1", "RightHandRing2", "RightHandRing3", "RightHandRing4", "RightHandPinky0", "RightHandPinky1", "RightHandPinky2", "RightHandPinky3", "RightHandPinky4", "RightPalm", "LeftUpLeg", "LeftLeg", "LeftFoot", "LeftToeBase", "LeftToe_End", "RightUpLeg", "RightLeg", "RightFoot", "RightToeBase", "RightToe_End" }; for (int i = 0; i < count; i++) { string boneName = i < boneNames.Length ? boneNames[i] : $"Bone_{i}"; bones[i] = new { boneName = boneName, position = new { x = UnityEngine.Random.Range(-1f, 1f), y = UnityEngine.Random.Range(-1f, 1f), z = UnityEngine.Random.Range(-1f, 1f) }, rotation = new { x = UnityEngine.Random.Range(-1f, 1f), y = UnityEngine.Random.Range(-1f, 1f), z = UnityEngine.Random.Range(-1f, 1f), w = UnityEngine.Random.Range(-1f, 1f) }, scale = new { x = 1f, y = 1f, z = 1f } }; } return bones; } object[] GenerateOldSystemBlendShapes(int meshCount, int weightsPerMesh) { object[] blendShapes = new object[meshCount]; string[] meshNames = { "Renderer_Head", "Renderer_EyeLeft", "Renderer_EyeRight", "Renderer_Teeth" }; for (int i = 0; i < meshCount; i++) { float[] weights = new float[weightsPerMesh]; for (int j = 0; j < weightsPerMesh; j++) { weights[j] = UnityEngine.Random.Range(0f, 100f); } blendShapes[i] = new { meshName = i < meshNames.Length ? meshNames[i] : $"Mesh_{i}", weights = weights }; } return blendShapes; } void ShowDetailedBreakdown() { int newSystemBones = GetNewSystemBoneCount(); int newSystemBlendShapes = GetNewSystemBlendShapeCount(); int totalOldBlendShapes = oldSystemMeshCount * oldSystemBlendShapesPerMesh; bool fullDataMode = GetUDPBroadcasterFullDataMode(); string currentMode = fullDataMode ? "FULL DATA" : "OPTIMIZED"; Debug.Log($"\nšŸ“‹ DETAILED BREAKDOWN:"); Debug.Log($"\nCurrent UDP System Configuration:"); Debug.Log($" • Mode: {currentMode}"); Debug.Log($" • Update Rate: {updateRate} Hz"); Debug.Log($" • Bones: {newSystemBones}"); Debug.Log($" • Blend Shapes: {newSystemBlendShapes}"); Debug.Log($"\nOld JSON System Issues:"); Debug.Log($" • {oldSystemBoneCount} bones with full transform data"); Debug.Log($" • {oldSystemMeshCount} meshes Ɨ {oldSystemBlendShapesPerMesh} blend shapes = {totalOldBlendShapes} facial weights"); Debug.Log($" • Verbose JSON with field names repeated"); Debug.Log($" • UTF-8 string encoding overhead"); Debug.Log($" • HTTP headers and protocol overhead"); Debug.Log($" • Requires Python server infrastructure"); Debug.Log($"\nNew UDP Binary Advantages:"); if (fullDataMode) { Debug.Log($" • {newSystemBones} bones (FULL avatar data)"); Debug.Log($" • {newSystemBlendShapes} facial blend shapes (ALL expressions)"); } else { Debug.Log($" • Only {newSystemBones} priority bones (most important)"); Debug.Log($" • {newSystemBlendShapes} key facial blend shapes only"); } Debug.Log($" • Compact binary format, no field names"); Debug.Log($" • Variable-size packets with length prefixes"); Debug.Log($" • Direct UDP broadcast, no server needed"); Debug.Log($" • Predictable network usage"); float boneReduction = (1f - (float)newSystemBones / oldSystemBoneCount) * 100f; float blendShapeReduction = (1f - (float)newSystemBlendShapes / totalOldBlendShapes) * 100f; Debug.Log($"\nData Reduction vs Old System:"); Debug.Log($" • Bones: {boneReduction:F1}% reduction ({oldSystemBoneCount} → {newSystemBones})"); Debug.Log($" • Blend Shapes: {blendShapeReduction:F1}% reduction ({totalOldBlendShapes} → {newSystemBlendShapes})"); } void ShowNetworkImpact(int jsonSize, int binarySize) { Debug.Log($"\n🌐 NETWORK IMPACT (at {updateRate} Hz):"); float jsonBandwidthKBps = (jsonSize * updateRate) / 1024f; float binaryBandwidthKBps = (binarySize * updateRate) / 1024f; Debug.Log($"Old System: {jsonBandwidthKBps:F1} KB/s per player"); Debug.Log($"New System: {binaryBandwidthKBps:F1} KB/s per player"); // Calculate for 3 player setup int playerCount = 3; Debug.Log($"\n3 Player Setup:"); Debug.Log($"Old System: {jsonBandwidthKBps * playerCount:F1} KB/s total"); Debug.Log($"New System: {binaryBandwidthKBps * playerCount:F1} KB/s total"); Debug.Log($"\nData usage per hour (single player):"); float oldMBPerHour = (jsonBandwidthKBps * 3600) / 1024; float newMBPerHour = (binaryBandwidthKBps * 3600) / 1024; Debug.Log($"Old System: {oldMBPerHour:F1} MB/hour"); Debug.Log($"New System: {newMBPerHour:F1} MB/hour"); Debug.Log($"Savings: {oldMBPerHour - newMBPerHour:F1} MB/hour ({((oldMBPerHour - newMBPerHour) / oldMBPerHour) * 100:F1}% reduction)"); } void ShowSystemComplexity() { float codeReduction = (1f - (float)newSystemTotalLines / oldSystemTotalLines) * 100f; Debug.Log($"\nāš™ļø SYSTEM COMPLEXITY:"); Debug.Log($"\nOld System Components:"); Debug.Log($" • avatar_sync_server.py"); Debug.Log($" • AvatarSyncClient.cs"); Debug.Log($" • AvatarDataUploader.cs"); Debug.Log($" • AvatarDataDownloader.cs"); Debug.Log($" • AvatarDataWriter.cs"); Debug.Log($" • AvatarDataReader.cs"); Debug.Log($" • Multiple serialization classes"); Debug.Log($" • HTTP client/server infrastructure"); Debug.Log($" Total: ~{oldSystemTotalLines:N0} lines of code"); Debug.Log($"\nNew System Components:"); Debug.Log($" • UDPAvatarBroadcaster.cs"); Debug.Log($" • UDPAvatarReceiver.cs"); Debug.Log($" • Simple binary serialization"); Debug.Log($" • No server infrastructure needed"); Debug.Log($" Total: ~{newSystemTotalLines:N0} lines of code"); Debug.Log($"\nāœ… New system is {codeReduction:F1}% less code and much simpler!"); Debug.Log($"Code reduction: {oldSystemTotalLines:N0} → {newSystemTotalLines:N0} lines ({oldSystemTotalLines - newSystemTotalLines:N0} lines removed)"); } void SaveComparisonToFile(int jsonSize, int binarySize) { try { // Calculate all metrics using dynamic values float compressionRatio = (float)jsonSize / binarySize; float bandwidthReduction = (1f - (float)binarySize / jsonSize) * 100f; float jsonBandwidthKBps = (jsonSize * updateRate) / 1024f; float binaryBandwidthKBps = (binarySize * updateRate) / 1024f; // Get calculated counts int newSystemBones = GetNewSystemBoneCount(); int newSystemBlendShapes = GetNewSystemBlendShapeCount(); int totalOldBlendShapes = oldSystemMeshCount * oldSystemBlendShapesPerMesh; bool fullDataMode = GetUDPBroadcasterFullDataMode(); string currentMode = fullDataMode ? "FULL DATA" : "OPTIMIZED"; // Create file content with just the data StringBuilder fileContent = new StringBuilder(); fileContent.AppendLine("Avatar Sync System Comparison Results"); fileContent.AppendLine($"Generated: {DateTime.Now:yyyy-MM-dd HH:mm:ss}"); fileContent.AppendLine(); // Size comparison fileContent.AppendLine("PACKET SIZE COMPARISON:"); fileContent.AppendLine($"Old JSON System: {jsonSize:N0} bytes ({jsonSize / 1024f:F2} KB)"); fileContent.AppendLine($"New UDP Binary: {binarySize:N0} bytes ({binarySize / 1024f:F2} KB)"); fileContent.AppendLine($"Compression Ratio: {compressionRatio:F1}x smaller"); fileContent.AppendLine($"Size Reduction: {bandwidthReduction:F1}%"); fileContent.AppendLine(); // Binary structure breakdown using calculated values int headerSize = 1 + 4 + 4 + 1; // playerID + sequenceNumber + timestamp + isFullDataMode int rootTransformSize = (3 + 4 + 3) * 4; int bonesSize = 4 + (newSystemBones * (3 + 4) * 4); int blendShapesSize = 4 + (newSystemBlendShapes * 4); fileContent.AppendLine("UDP BINARY STRUCTURE:"); fileContent.AppendLine($"Header: {headerSize} bytes"); fileContent.AppendLine($"Root Transform: {rootTransformSize} bytes"); fileContent.AppendLine($"Bones ({newSystemBones}): {bonesSize} bytes"); fileContent.AppendLine($"Blend Shapes ({newSystemBlendShapes}): {blendShapesSize} bytes"); fileContent.AppendLine($"Total: {binarySize} bytes"); fileContent.AppendLine(); // Bandwidth impact at configured rate fileContent.AppendLine($"BANDWIDTH USAGE ({updateRate} Hz):"); fileContent.AppendLine($"Old System: {jsonBandwidthKBps:F1} KB/s per player"); fileContent.AppendLine($"New System: {binaryBandwidthKBps:F1} KB/s per player"); fileContent.AppendLine(); // System details fileContent.AppendLine("SYSTEM DETAILS:"); fileContent.AppendLine($"Update Rate: {updateRate} Hz"); fileContent.AppendLine($"UDP Mode: {currentMode}"); fileContent.AppendLine($"Old System: {oldSystemBoneCount} bones, {totalOldBlendShapes} blend shapes ({oldSystemMeshCount} meshes Ɨ {oldSystemBlendShapesPerMesh})"); fileContent.AppendLine($"New System: {newSystemBones} bones, {newSystemBlendShapes} blend shapes"); fileContent.AppendLine(); // 3 Player setup bandwidth int players = 3; float oldTotal = jsonBandwidthKBps * players; float newTotal = binaryBandwidthKBps * players; fileContent.AppendLine("3 PLAYER SETUP BANDWIDTH:"); fileContent.AppendLine($"Old System: {oldTotal:F1} KB/s total"); fileContent.AppendLine($"New System: {newTotal:F1} KB/s total"); fileContent.AppendLine($"Bandwidth Savings: {oldTotal - newTotal:F1} KB/s ({((oldTotal - newTotal) / oldTotal) * 100:F1}% reduction)"); fileContent.AppendLine(); // Data usage per hour float oldMBPerHour = (jsonBandwidthKBps * 3600) / 1024; float newMBPerHour = (binaryBandwidthKBps * 3600) / 1024; fileContent.AppendLine("DATA USAGE PER HOUR (single player):"); fileContent.AppendLine($"Old System: {oldMBPerHour:F1} MB/hour"); fileContent.AppendLine($"New System: {newMBPerHour:F1} MB/hour"); fileContent.AppendLine($"Savings: {oldMBPerHour - newMBPerHour:F1} MB/hour ({((oldMBPerHour - newMBPerHour) / oldMBPerHour) * 100:F1}% reduction)"); fileContent.AppendLine(); // Code complexity float codeReduction = (1f - (float)newSystemTotalLines / oldSystemTotalLines) * 100f; fileContent.AppendLine("CODE COMPLEXITY:"); fileContent.AppendLine($"Old System: ~{oldSystemTotalLines:N0} lines (6 components + Python server)"); fileContent.AppendLine($"New System: ~{newSystemTotalLines:N0} lines (2 components, no server)"); fileContent.AppendLine($"Code Reduction: {codeReduction:F1}% ({oldSystemTotalLines - newSystemTotalLines:N0} lines removed)"); fileContent.AppendLine(); // Performance characteristics fileContent.AppendLine("PERFORMANCE CHARACTERISTICS:"); fileContent.AppendLine("Old System: HTTP request/response, JSON parsing, server dependency"); fileContent.AppendLine("New System: UDP broadcast, binary format, peer-to-peer"); fileContent.AppendLine("Latency: Local network UDP (~1-10ms vs HTTP ~10-50ms)"); fileContent.AppendLine("Infrastructure: None required (vs Python server)"); // Write to file string filePath = Path.Combine(Application.dataPath, outputFileName); File.WriteAllText(filePath, fileContent.ToString()); Debug.Log($"Comparison data saved to: {filePath}"); } catch (Exception e) { Debug.LogError($"Failed to save comparison to file: {e.Message}"); } } void OnGUI() { if (GUI.Button(new Rect(10, Screen.height - 40, 200, 30), "Run Comparison")) { RunComparison(); } if (GUI.Button(new Rect(220, Screen.height - 40, 150, 30), "Save to File")) { var jsonSize = CalculateJSONSystemSize(); var binarySize = CalculateUDPBinarySize(); SaveComparisonToFile(jsonSize, binarySize); } } }