Advertisement
Guest User

Untitled

a guest
Oct 19th, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.28 KB | None | 0 0
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5.  
  6. namespace tmp
  7. {
  8.     public class StringSegments
  9.     {
  10.         public static void Do()
  11.         {
  12.             Console.WriteLine("Baseline");
  13.             BaseLine();
  14.             GC.Collect(2);
  15.             Console.WriteLine("Optimized");
  16.             Optimized();
  17.         }
  18.  
  19.         private static void BaseLine()
  20.         {
  21.             Console.WriteLine(GC.GetGCMemoryInfo().HeapSizeBytes / 1024 / 1024);
  22.             var segments = Enumerable.Range(1, 10).Select(s => Guid.NewGuid().ToString("N")).ToArray();
  23.             var items = new List<string>();
  24.             var r = new Random();
  25.             for (int i = 0; i < 10_000_000; i++)
  26.             {
  27.                 var item = string.Concat(
  28.                     segments[r.Next(0,9)], "_",
  29.                     segments[r.Next(0,9)], "_",
  30.                     segments[r.Next(0,9)]);
  31.                 items.Add(item);
  32.             }
  33.             GC.Collect(2);
  34.             Console.WriteLine(GC.GetGCMemoryInfo().HeapSizeBytes / 1024 / 1024);
  35.             Console.ReadKey();
  36.         }
  37.        
  38.         private static void Optimized()
  39.         {
  40.             Console.WriteLine(GC.GetGCMemoryInfo().HeapSizeBytes / 1024 / 1024);
  41.             var segments = Enumerable.Range(1, 10).Select(s => Guid.NewGuid().ToString("N")).ToArray();
  42.             var items = new List<StringSegment>();
  43.             var r = new Random();
  44.             for (int i = 0; i < 10_000_000; i++)
  45.             {
  46.                 var item = string.Concat(
  47.                     segments[r.Next(0,9)], "_",
  48.                     segments[r.Next(0,9)], "_",
  49.                     segments[r.Next(0,9)]);
  50.                 items.Add(item);
  51.             }
  52.             GC.Collect(2);
  53.             Console.WriteLine(GC.GetGCMemoryInfo().HeapSizeBytes / 1024 / 1024);
  54.             Console.ReadKey();
  55.         }
  56.     }
  57.  
  58.     public class StringSegment
  59.     {
  60.         static ConcurrentDictionary<int, X> hashMap = new ConcurrentDictionary<int,X>();
  61.  
  62.         private const char Delimiter = '_';
  63.         private readonly List<int> _segments;
  64.  
  65.         private StringSegment(List<int> segments) => _segments = segments;
  66.  
  67.         public static implicit operator StringSegment(string src) => FromString(src);
  68.  
  69.         private static StringSegment FromString(string src)
  70.         {
  71.             var refs = new List<int>();
  72.             var segments = src.Split(Delimiter, StringSplitOptions.RemoveEmptyEntries);
  73.             foreach (var segment in segments)
  74.             {
  75.                 var hash = segment.GetHashCode();
  76.                 if (hashMap.TryGetValue(hash, out var existing))
  77.                 {
  78.                     existing.Inc();
  79.                     refs.Add(hash);
  80.                 }
  81.                 else
  82.                 {
  83.                     hashMap.TryAdd(hash, new X(segment, 1));
  84.                     refs.Add(hash);
  85.                 }
  86.             }
  87.             return new StringSegment(refs);
  88.         }
  89.  
  90.         public override string ToString()
  91.         {
  92.             var a = new List<string>();
  93.             foreach (var segment in _segments)
  94.             {
  95.                 if (!hashMap.TryGetValue(segment, out var str))
  96.                 {
  97.                     throw new Exception("original data is destroyed!");
  98.                 }
  99.  
  100.                 a.Add(str.value);
  101.             }
  102.             return string.Join(Delimiter, a);
  103.         }
  104.        
  105.         ~StringSegment()
  106.         {
  107.             foreach (var segment in _segments)
  108.             {
  109.                 if (hashMap.TryGetValue(segment, out var existing))
  110.                 {
  111.                     existing.Dec();
  112.                     if (existing.count <= 0)
  113.                     {
  114.                         hashMap.TryRemove(segment, out _);
  115.                     }
  116.                 }
  117.             }
  118.         }
  119.        
  120.        
  121.     }
  122.  
  123.     public class X
  124.     {
  125.         public X(string value, int count)
  126.         {
  127.             this.value = value;
  128.             this.count = count;
  129.         }
  130.         public string value { get; }
  131.         public int count { get; private set; }
  132.  
  133.         public void Dec() => count--;
  134.         public void Inc() => count++;
  135.         public override string ToString() => $"{value}:{count}";
  136.     }
  137. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement