Как такое быстро считать?
От: peer  
Дата: 20.02.25 17:46
Оценка:
Есть массив объектов класса Client. Массив приличный, порядка 100К строк
Внутри класса Client есть несколько полей которые высчитываются и в базе не хранятся.
Status высчитывается через внешний класс, т.к. еще есть другие классы где используется метод Define

пример
class Client 

    //эти поля в базе
   decimal CurrentCashAmount
   int Age 
   decimal LastYearCashAmount
   decimal CurrentMonthExpenses

   //эти поля динамически считаются
   string Status = StatusDefinder.Define(CurrentCashAmount, LastYearCashAmount, CurrentMonthExpenses, Age) 


static struct StatusDefinder

   static string Define(CurrentCashAmount, LastYearCashAmount, CurrentMonthExpenses, Age) 
   {
     if (Age > 25)
        if (CurrentCashAmount > 3000000 && LastYearCashAmount > 3000000 && CurrentMonthExpenses > 50000)
       return "Vip";
        else 
           return "NonVip";
     else 
      if (CurrentCashAmount > 4000000 && LastYearCashAmount > 4000000 && CurrentMonthExpenses > 70000)
       return "Vip";
        else 
           return "NonVip";
   }



вопрос: как максимально быстро и с минимальными расходами сделать расчет статуса? struct\class\record readonly\static
Re: Как такое быстро считать?
От: RushDevion Россия  
Дата: 20.02.25 19:53
Оценка:
P>вопрос: как максимально быстро и с минимальными расходами сделать расчет статуса? struct\class\record readonly\static
А что, скорости обычного цикла for не хватает? Почему?

Ну попробуй через Parallel
Parallel.For(0, clients.Lenght-1, i => {
  clients[i].Status = ...
});


А вообще, чтобы посоветовать что-то небанальное, нужно понимать, как происходит работа с этими данными (кто и как часто их читает, изменяет, перевычисляет).
Re[2]: Как такое быстро считать?
От: peer  
Дата: 20.02.25 20:22
Оценка:
Здравствуйте, RushDevion, Вы писали:

P>>вопрос: как максимально быстро и с минимальными расходами сделать расчет статуса? struct\class\record readonly\static

RD>А что, скорости обычного цикла for не хватает? Почему?

RD>Ну попробуй через Parallel

RD>
RD>Parallel.For(0, clients.Lenght-1, i => {
RD>  clients[i].Status = ...
RD>});
RD>


RD>А вообще, чтобы посоветовать что-то небанальное, нужно понимать, как происходит работа с этими данными (кто и как часто их читает, изменяет, перевычисляет).


меняют редко, раз в неделю.
читают средне, раз 50 в день, но объем вот написал какой.

вопрос больше был не в цикле, а есть ли смысл делать структуру или ридонли поля для оптимизаций или не будет ли static тормозом тут?
Re[3]: Как такое быстро считать?
От: RushDevion Россия  
Дата: 20.02.25 20:50
Оценка: +3
P>меняют редко, раз в неделю.
P>читают средне, раз 50 в день, но объем вот написал какой.

P>вопрос больше был не в цикле, а есть ли смысл делать структуру или ридонли поля для оптимизаций или не будет ли static тормозом тут?


Т.е. есть приложение, которому нужно держать в памяти 100K таких записей
(опять же непонятно зачем держать это именно в памяти, а не брать каждый раз из БД, ну да ладно).
И раз в неделю их пересчитывать? Зачем тут вообще что-то оптимизировать при таких вводных?
Любой вариант будет работать приемлемо быстро.
А микрооптимизации (struct vs class, readonly и т.п.) принципиально ничего не поменяют.
Re[4]: Как такое быстро считать?
От: peer  
Дата: 21.02.25 04:10
Оценка:
Здравствуйте, RushDevion, Вы писали:

P>>меняют редко, раз в неделю.

P>>читают средне, раз 50 в день, но объем вот написал какой.

P>>вопрос больше был не в цикле, а есть ли смысл делать структуру или ридонли поля для оптимизаций или не будет ли static тормозом тут?


RD>Т.е. есть приложение, которому нужно держать в памяти 100K таких записей

RD>(опять же непонятно зачем держать это именно в памяти, а не брать каждый раз из БД, ну да ладно).
RD>И раз в неделю их пересчитывать? Зачем тут вообще что-то оптимизировать при таких вводных?
RD>Любой вариант будет работать приемлемо быстро.
RD>А микрооптимизации (struct vs class, readonly и т.п.) принципиально ничего не поменяют.

я честно говоря тут немного код изменил по некоторым критериям, хотел понять насчет микрооптимизаций,
но вот что задумался так это что изначально планировался вариант с полем внутри класса, а у вас вариант предложенный с циклом

class Client 

    //эти поля в базе
   decimal CurrentCashAmount
   int Age 
   decimal LastYearCashAmount
   decimal CurrentMonthExpenses

   //эти поля динамически считаются
   string Status = StatusDefinder.Define(CurrentCashAmount, LastYearCashAmount, CurrentMonthExpenses, Age) 



Parallel.For(0, clients.Lenght-1, i => {
  clients[i].Status = ...
});


ваш вариант предложен чисто из оптимизационных мыслей или в моем варианте есть недостатки?
по идее в вашем варианте нужно знать что надо вызвать проставление статуса, а в моем всё само высчитается
Re[5]: Как такое быстро считать?
От: RushDevion Россия  
Дата: 21.02.25 08:20
Оценка: +1
P>ваш вариант предложен чисто из оптимизационных мыслей или в моем варианте есть недостатки?
P>по идее в вашем варианте нужно знать что надо вызвать проставление статуса, а в моем всё само высчитается

Мой вариант — это простейший способ распараллелить вычисление статуса, только и всего.
Того же результата можно добиться, не меняя твой код.
var clients = new Client[100_000];
Parallel.For(0, clients.Lenght-1, i => { 
  clients[i] = new Client(...); // Здесь статус посчитается в процессе инициализации объекта
});


А с точки зрения чистоты ООП-дизайна я бы, скорее, вообще убрал поле Status из сущности клиента.
Раз уж на статус могу влиять самые разные внешние факторы (e.g. какие-то сезонные акции, например), то логичнее выделить его вычисление в отдельный доменный сервис.
Кроме того, не видя модификаторов доступа, непонятно, можно ли снаружи класса Client простым присваиванием поменять CurrentCashAmount, LastYearCashAmount и т.п.
Если можно, то это автоматически делает вычисленный статус невалидным, соответственно, хранить его бессмысленно.

Далее. Неужели всем эти 100_000K клиентов обязательно нужно знать статус именно в момент создания?
Может быть активная работа идет только с некоторым подмножеством клиентов, а остальные бесполезно висят в памяти, ждут, когда же к ним обратятся.
Если так, то и статус можно вычислять лениво, в момент обращения.
Типа такого:
class CurrentCashAmount {
   private string _status;
   public string Status => _status ??= StatusDefinder.Define(CurrentCashAmount, LastYearCashAmount, CurrentMonthExpenses, Age)
}
Re: Как такое быстро считать?
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.02.25 07:58
Оценка: +2
Здравствуйте, peer, Вы писали:

P>Есть массив объектов класса Client. Массив приличный, порядка 100К строк

P>Внутри класса Client есть несколько полей которые высчитываются и в базе не хранятся.
Сразу непонятно: так "массив" или "в базе"?
Обычно, когда что-то хранится в БД, архитекторы избегают подъёма всей таблицы в память — потому что нафига?
Надо бы прояснить подробности архитектуры.

P>Status высчитывается через внешний класс, т.к. еще есть другие классы где используется метод Define

Ну и прекрасно. Высчитывается и высчитывается.

P>вопрос: как максимально быстро и с минимальными расходами сделать расчет статуса? struct\class\record readonly\static

Опять непонятно. Вам нужен расчёт статуса для одного клиента? Тогда почему речь о массиве и его размере?
Нужен статус для всех — опять же, зачем?
Зачем вообще делать его полем — ведь можно его описать вычисляемым свойством, пусть и через внешний метод?

Чтобы вам хоть что-то посоветовать, нужно знать сценарий(и) использования этого статуса.
Что вы потом собираетесь с ним делать? Фильтровать ваши 100к клиентов по статусу? Делать в цикле какие-то расчёты, которые от статуса зависят?
Или вам нужно где-то при обработке какого-то клиента в рамках конкретного метода контроллера ветвиться по этому статусу?

Вот эти вопросы вас должны волновать.
А мелкие оптимизации типа выбора между статическим методом и методом экземпляра потребуются тогда, когда вы определитесь с более крупной задачей.
Там — всё просто: берём в руки https://sharplab.io/ и https://benchmarkdotnet.org/. Второй поможет понять, какое из микрорешений быстрее, а первый — почему.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Как такое быстро считать?
От: bobby23  
Дата: 25.02.25 14:40
Оценка: :))
Здравствуйте, peer, Вы писали:

P>Есть массив объектов класса Client. Массив приличный, порядка 100К строк

P>Внутри класса Client есть несколько полей которые высчитываются и в базе не хранятся.
P>Status высчитывается через внешний класс, т.к. еще есть другие классы где используется метод Define

P>пример

P>[cs]
P>class Client

P> //эти поля в базе

P> decimal CurrentCashAmount
P> int Age
P> decimal LastYearCashAmount
P> decimal CurrentMonthExpenses

P> //эти поля динамически считаются

P> string Status = StatusDefinder.Define(CurrentCashAmount, LastYearCashAmount, CurrentMonthExpenses, Age)


запустить редис и в него сохранять client_id, calculated_status
Отредактировано 25.02.2025 14:42 bobby23 . Предыдущая версия .
Re: Как такое быстро считать?
От: Janus Россия  
Дата: 26.02.25 19:55
Оценка: +1
Здравствуйте, peer, Вы писали:

P>Есть массив объектов класса Client. Массив приличный, порядка 100К строк

P>Внутри класса Client есть несколько полей которые высчитываются и в базе не хранятся.
P>Status высчитывается через внешний класс, т.к. еще есть другие классы где используется метод Define

А какая база ? Иногда подобнее расчёты проще и быстрее выполнить в БД
... Хорошо уметь читать между строк. Это иногда
приносит большую пользу
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.