Есть массив объектов класса 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
P>вопрос: как максимально быстро и с минимальными расходами сделать расчет статуса? struct\class\record readonly\static
А что, скорости обычного цикла for не хватает? Почему?
Ну попробуй через Parallel
Parallel.For(0, clients.Lenght-1, i => {
clients[i].Status = ...
});
А вообще, чтобы посоветовать что-то небанальное, нужно понимать, как происходит работа с этими данными (кто и как часто их читает, изменяет, перевычисляет).
Здравствуйте, RushDevion, Вы писали:
P>>вопрос: как максимально быстро и с минимальными расходами сделать расчет статуса? struct\class\record readonly\static RD>А что, скорости обычного цикла for не хватает? Почему?
RD>Ну попробуй через Parallel RD>
RD>А вообще, чтобы посоветовать что-то небанальное, нужно понимать, как происходит работа с этими данными (кто и как часто их читает, изменяет, перевычисляет).
меняют редко, раз в неделю.
читают средне, раз 50 в день, но объем вот написал какой.
вопрос больше был не в цикле, а есть ли смысл делать структуру или ридонли поля для оптимизаций или не будет ли static тормозом тут?
P>меняют редко, раз в неделю. P>читают средне, раз 50 в день, но объем вот написал какой.
P>вопрос больше был не в цикле, а есть ли смысл делать структуру или ридонли поля для оптимизаций или не будет ли static тормозом тут?
Т.е. есть приложение, которому нужно держать в памяти 100K таких записей
(опять же непонятно зачем держать это именно в памяти, а не брать каждый раз из БД, ну да ладно).
И раз в неделю их пересчитывать? Зачем тут вообще что-то оптимизировать при таких вводных?
Любой вариант будет работать приемлемо быстро.
А микрооптимизации (struct vs class, readonly и т.п.) принципиально ничего не поменяют.
Здравствуйте, 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 = ...
});
ваш вариант предложен чисто из оптимизационных мыслей или в моем варианте есть недостатки?
по идее в вашем варианте нужно знать что надо вызвать проставление статуса, а в моем всё само высчитается
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)
}
Здравствуйте, peer, Вы писали:
P>Есть массив объектов класса Client. Массив приличный, порядка 100К строк P>Внутри класса Client есть несколько полей которые высчитываются и в базе не хранятся.
Сразу непонятно: так "массив" или "в базе"?
Обычно, когда что-то хранится в БД, архитекторы избегают подъёма всей таблицы в память — потому что нафига?
Надо бы прояснить подробности архитектуры.
P>Status высчитывается через внешний класс, т.к. еще есть другие классы где используется метод Define
Ну и прекрасно. Высчитывается и высчитывается.
P>вопрос: как максимально быстро и с минимальными расходами сделать расчет статуса? struct\class\record readonly\static
Опять непонятно. Вам нужен расчёт статуса для одного клиента? Тогда почему речь о массиве и его размере?
Нужен статус для всех — опять же, зачем?
Зачем вообще делать его полем — ведь можно его описать вычисляемым свойством, пусть и через внешний метод?
Чтобы вам хоть что-то посоветовать, нужно знать сценарий(и) использования этого статуса.
Что вы потом собираетесь с ним делать? Фильтровать ваши 100к клиентов по статусу? Делать в цикле какие-то расчёты, которые от статуса зависят?
Или вам нужно где-то при обработке какого-то клиента в рамках конкретного метода контроллера ветвиться по этому статусу?
Вот эти вопросы вас должны волновать.
А мелкие оптимизации типа выбора между статическим методом и методом экземпляра потребуются тогда, когда вы определитесь с более крупной задачей.
Там — всё просто: берём в руки https://sharplab.io/ и https://benchmarkdotnet.org/. Второй поможет понять, какое из микрорешений быстрее, а первый — почему.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, 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
Здравствуйте, peer, Вы писали:
P>Есть массив объектов класса Client. Массив приличный, порядка 100К строк P>Внутри класса Client есть несколько полей которые высчитываются и в базе не хранятся. P>Status высчитывается через внешний класс, т.к. еще есть другие классы где используется метод Define
А какая база ? Иногда подобнее расчёты проще и быстрее выполнить в БД
... Хорошо уметь читать между строк. Это иногда
приносит большую пользу