C# Оптимизация оперативной памяти

Поділитися
Вставка
  • Опубліковано 26 січ 2025

КОМЕНТАРІ • 38

  • @СерегаБ-б3н
    @СерегаБ-б3н 2 роки тому +2

    Спасибо Александр, очень круто и полезно! Хоть я и новичок))

    • @Kulibins1
      @Kulibins1  2 роки тому +1

      Рад что нравится

  • @andreyt1818
    @andreyt1818 2 роки тому +2

    В одном проекте была у меня реализация интернированной строки вместо String типа.
    не только в целях оптимизации памяти, но еще надо было сравнивать/искать эти строки
    а для интернированыхх строк сравнение(на равенство) сводится к сравнению ссылок,
    т.к в во внутренний пул интернировааные строки запихиваются используя ordinal сравнение (побайтно)
    это нам вполне подходило.
    хороший канал - лайк, подписка ))

    • @Kulibins1
      @Kulibins1  2 роки тому +1

      Да как раз в одном посте было предложено упростить словари, а я изначально это делал что бы ускорить обмен информацией, а вот оптимизация ОЗУ это был побочный эффект, потом уже целенаправленно занимался оптимизацией. За лайк и подписку спасибо.

    • @Kulibins1
      @Kulibins1  2 роки тому +1

      @@IQ-120 у меня стаж 22+ года работы. И да я в своё время и на asm писал. Упор был на simd команды ( но это было давно ) + то что показал в этом виде это важно, и ничего сложного в этом нет. Про исследования мне до Рихтера далеко 🤣

    • @Kulibins1
      @Kulibins1  2 роки тому

      @@IQ-120 юморист 🤣 Запись и монтаж видео занимает много времени эгоизм должен быть очень большой 😁. У меня это хобби.

    • @Kulibins1
      @Kulibins1  2 роки тому +2

      @@IQ-120 тут несколько мнений. 1) опытный разработчик работает и он молодец 2) опытный еще делится опытом. В общем предлагаю прекращать чатится. А если есть желание, велком в телегу

  • @Дмитрийсекрет-н7о
    @Дмитрийсекрет-н7о 2 роки тому +2

    Интересная хитрость.

  • @sergeypinaev4376
    @sergeypinaev4376 2 роки тому +1

    Очень круто! Спасибо

    • @Kulibins1
      @Kulibins1  2 роки тому +1

      Всегда пожалуйста

  • @vinogradova619
    @vinogradova619 2 роки тому +4

    Классное видео, а можно подробнее про диагностику в целом сделать видео?

    • @Kulibins1
      @Kulibins1  2 роки тому +1

      Конечно, сделаю такое видео тоже

  • @sivtsev
    @sivtsev 2 роки тому +3

    👌К активному применению. Единственным минусом данного финта представляется большее потребление процессорного времени на поиск в кэше в приложениях с активным созданием/удалением объектов с такими строками. Тут кому что важнее, как говорится.

    • @Kulibins1
      @Kulibins1  2 роки тому +2

      Да так и есть

  • @blowin8273
    @blowin8273 2 роки тому +2

    Добрый день, а почему бы не сделать 1 ConcurrentDictionary?
    Идея такая, что при установки значения, мы по ключу ищем значение, если оно там есть, то мы используем его(интернированную строку), если его нет, то мы добавляем её следующим образом
    map.TryAdd(strValue, strValue);
    Т.е мы избавляемся от 2х словарей и уменьшаем количество потребляемой оперативной памяти + ускоряем работу этого кэша

    • @Kulibins1
      @Kulibins1  2 роки тому +2

      Тоже как вариант. Только у меня было такое, я передавал сам дикшенари из строк и интов и сами объекты где строки это числа, и тогда количество передаваемой информации сильно меньше

    • @konstantinshapovalov3520
      @konstantinshapovalov3520 2 роки тому +1

      @@Kulibins1 в случае ConcurrentDictionary int не нужны совсем, как и обращение к словарю и приведение типов, при возврате строки из кэша. Вот пример реализации:
      public struct StringCache
      {
      private string cachedStr;
      public static implicit operator StringCache(string str) =>
      new() { cachedStr = StringCacheManager.Instance.Cache(ref str) };
      public static implicit operator string(StringCache s) => s.cachedStr;
      public static string[] CacheArray(string[] arr)
      {
      for (int i = 0; i < arr.Length; i++)
      arr[i] = StringCacheManager.Instance.Cache(ref arr[i]);
      return arr;
      }
      public override string ToString() => cachedStr;
      }
      internal class StringCacheManager
      {
      public static readonly StringCacheManager Instance = new();
      private readonly ConcurrentDictionary cacheStorage = new();
      public string Cache(ref string str)
      {
      if (string.IsNullOrEmpty(str))
      return String.Empty;
      if (cacheStorage.TryAdd(str, str))
      return str;
      return cacheStorage[str];
      }
      }

    • @Kulibins1
      @Kulibins1  2 роки тому +1

      @@konstantinshapovalov3520 уже писали. Только код я скопировал из проекта где мне нужен был int, т.к. я серелизовал и там передавал int. А так спасибо за активность 👍

    • @konstantinshapovalov3520
      @konstantinshapovalov3520 2 роки тому +1

      @@Kulibins1 Спасибо за идею кстати, сейчас добавил в свой проект. Имхо код класс StringCache StringCacheManager с int и без не плохо было бы на гитхаб тоже выложить. Кстати во втором случае после загрузки данных хранить ConcurrentDictionary не обязательно и можно очистить, а данные все останутся. Освободится доп. память ;)

  • @Adel__007
    @Adel__007 2 роки тому +1

    круто!

  • @stridemann2338
    @stridemann2338 Рік тому

    Спасибо, очень интересно
    Вместо обжекта который хранит лист или дикшнри было бы лучше сделать через полиморфизм как State паттерн чтобы без кастов было? По идее должно быть чутка быстрее. + имплементацию делать структурой а не объектом чтоб вызовы были быстрее и jit оптимизация получше.

    • @Kulibins1
      @Kulibins1  Рік тому +1

      Да, можно с оптимизировать еще.

  • @konstantinshapovalov3520
    @konstantinshapovalov3520 2 роки тому +1

    Вдруг кому пригодится реализация на HashSet:
    public struct StringCache
    {
    private string cachedStr;
    public static implicit operator string(StringCache s) => s.cachedStr;
    public static explicit operator StringCache(string str) =>
    new() { cachedStr = StringCacheManager.Instance.Cache(ref str) };
    public static string[] CacheArray(string[] arr)
    {
    for (int i = 0; i < arr.Length; i++)
    arr[i] = StringCacheManager.Instance.Cache(ref arr[i]);
    return arr;
    }
    public static void ClearCache() => StringCacheManager.Instance.ClearCache();
    public override string ToString() => cachedStr;
    }
    internal class StringCacheManager : IDisposable
    {
    public static readonly StringCacheManager Instance = new();
    private readonly HashSet cacheStorage = new();
    private readonly ReaderWriterLockSlim cacheLock = new();
    public bool IsDisposed { get; private set; }
    private StringCacheManager()
    {
    Debug.Assert(Instance == null, "Should be one instance of StringCacheManager");
    }
    public string Cache(ref string str)
    {
    if (IsDisposed)
    throw new ObjectDisposedException(nameof(StringCacheManager));
    if (string.IsNullOrEmpty(str))
    return String.Empty;
    cacheLock.EnterReadLock();
    try
    {
    if (cacheStorage.TryGetValue(str, out var cacheStr))
    return cacheStr;
    }
    finally
    {
    cacheLock.ExitReadLock();
    }
    cacheLock.EnterWriteLock();
    try
    {
    if(cacheStorage.Add(str))
    return str;
    if (cacheStorage.TryGetValue(str, out var cacheStr))
    return cacheStr;
    }
    finally
    {
    cacheLock.ExitWriteLock();
    }
    return str;
    }
    public void ClearCache()
    {
    if (IsDisposed)
    throw new ObjectDisposedException(nameof(StringCacheManager));
    cacheLock.EnterWriteLock();
    try
    {
    cacheStorage.Clear();
    }
    finally
    {
    cacheLock.ExitWriteLock();
    }
    }
    public void Dispose()
    {
    cacheLock?.Dispose();
    IsDisposed = true;
    }
    }

    • @Kulibins1
      @Kulibins1  2 роки тому +1

      Хорошая реализация 👍

  • @meosaganami5472
    @meosaganami5472 Рік тому

    Не совсем понимаю, где это вы в базе столько одинаковых строк нарыли

    • @Kulibins1
      @Kulibins1  Рік тому

      Вроде же рассказал что есть произвольное дерево. Каждый элемент дерева это тэг с устройства, заранее не известны эти тэги и очень зависят от устройств. Но тут есть множество повторений, вот одинаковые строки и оптимизируются. На самом деле много где это может быть. В документных базах данных и т.д.

  • @krivodeling7925
    @krivodeling7925 6 місяців тому +1

    +

  • @АнтонБ-х9у
    @АнтонБ-х9у 11 місяців тому

    Ушел от рич модели классов на анемик. Подобных проблем нет, так как нет самой необходимости в событиях 😂
    Ооп это зло.

    • @Kulibins1
      @Kulibins1  11 місяців тому +1

      события это как пример. думаю дерево чего-нибудь у многих есть, так же как событие, например клик.

    • @АнтонБ-х9у
      @АнтонБ-х9у 11 місяців тому

      @@Kulibins1 деревья были, сейчас нет, а если и есть, то они в бд 😁
      Если поменять концепцию на cqs + anemic, то там архитектура любых приложений вообще по другому строится, и она проще, производительней легче расширяется и в ней меньше ошибок в следствии её некоторой простоты и дубовости 😁
      Было время, были события, деревья, но теперь в одно лицо 200+ микросервисов без ошибок вообще не напрягаясь.

    • @Kulibins1
      @Kulibins1  11 місяців тому +1

      @@АнтонБ-х9у модель данных это не то о чём это видео. то что у вас дерево в базе данных => вы вообще не поняли суть темы

    • @АнтонБ-х9у
      @АнтонБ-х9у 11 місяців тому

      @@Kulibins1 я понял, надесь и вы поняли, что если сделать архитектуру кода другой, то ваша тема просто никогда не возникнет в вашем проекте 😁

  • @Bont1860
    @Bont1860 2 роки тому +1

    Будьте добры, кто-нибудь, объясните строку
    **public int this[string value]**

    • @Kulibins1
      @Kulibins1  2 роки тому +2

      Индексатор принимает строку возвращает число. У меня строке соответствует число. Впринципе можно было сделать фенцию. int GetInt(string value) но с индексатором вызов короче вместо о.GetInt("ля-ля-ля") будет o["ля-ля-ля"]

    • @Bont1860
      @Bont1860 2 роки тому +1

      @@Kulibins1 спасибо большое, почитал про индексаторы, был пробел в знаниях.

  • @Bont1860
    @Bont1860 2 роки тому +1

    Очень напрягает затыки звука. Резко пропадает звук. Заставляет напрагяться

    • @Kulibins1
      @Kulibins1  2 роки тому +2

      В новых видео такого нет. Шумодав...