Автор объясняет суть атомарности и объясняет правильно, вы же просто докапываетесь до мышей или до блох. Разумеется, в транзакции "ошибка" а-ля исключение, может быть перехвачена, а rollback может быть вызван без исключения-ошибки, на основе проверки бизнес-условий. Понятно почему автор не стал останавливаться на таких тривиальностях. Непонятно почему вы преподносите эти тривиальности с таким апломбом.
В структурах есть ссылочные типы, такие как String.
А почему не надо заменять классы структурами, если в структуре есть ссылочные типы? Что плохого случится, если я заменю record User(string Name, int Age) на readonly record struct User(string Name, int Age) ?
>Итак, предположим, у нас есть класс с массивами и структура с массивами . В первом случае массивы будут храниться в оперативной памяти нашего приложения, а во втором — в кэше процессора (с учетом некоторых особенностей сборки мусора, которые мы обсудим ниже).
Судя по примерам ниже, у вас речь не про классы/структуры с массивами, а про массивы классов и структур. Так дальнейшие рассуждения приобретают рамки хоть какого-то смысла. Т.е., становится понятно, что хотел сказать автор, но смысла в сказанном всё равно остаётся не много.
1. Структуры не хранятся в оперативной памяти? 2. Структуры гарантированно находятся в кэше процессора? 3. Классы не могут помещаться в кэш процессора?
А вот shrplab для обоих ваших вариантов с обходом цикла - и для "плохого" (где numbers[i]*numbers[i]) и для "хорошего" (где num*num) выдаёт одинаковый Asm Code. Выходит, компилятор запросто справляется с такого рода оптимизациями...
Продукт-менеджер ставит продуктовые задачи, а её декомпозицию на задачи разработчиков осуществляет тимлид. Вот он и должен принимать MR. Если на одного человека оказывается много нагрузки, а в команде достаточно сеньоров, то обязанности можно делить и тогда каждый сеньор будет "тимлидом" для своей _продуктовой_ задачи. Главное тут чтобы тот, кто проверяет MR, был глубоко погружён в проблематику общей (продуктовой) задачи, это лекарство от формальных ревью. И обычно этот человек тот, кто осуществил декомпозицию.
Вариант со stackalloc не для всякого размера строки подойдёт из-за StackOverflowException,хорошо бы про такие вещи упоминать.
Аллокацию памяти можно свести до нуля, если ввести флаг hasWhitespaces и устанавливать его в цикле при встрече пробельного символа. Тогда в случае hasWhitespaces=false можно возвращать исходную строку не создавая новую. Но осмысленность такой оптимизации зависит от контекста: как часто в рассматриваемом сценарии будут встречаться строки без пробельных символов и готовы ли вы за отсутствие аллокации в некоторых случаях платить расходом нескольких дополнительных тактов процессора в случае каждом.
В примере с буфером размер строки известен, в примере с ToArray используется итератор, ToArray в данном случае не может делать предположений о конечном размере коллекции.
P.S. Если бы ToArray к ICollection применялся, тогда другое дело, вот что у метода ToArray() под капотом.
if (source is ICollection<TSource> collection)
{
return ICollectionToArray(collection);
}
private static TSource[] ICollectionToArray<TSource>(ICollection<TSource> collection)
{
int count = collection.Count;
if (count != 0)
{
var result = new TSource[count];
collection.CopyTo(result, 0);
return result;
}
return [];
}
Запрос на ревью должен быть в приоритете у проверяющего, тогда MR не будет долго мариноваться. Если ты не можешь прервать свой "поток", тогда тебе лучше не заниматься код-ревью.
Проверять код должен тот, кто ставил задачу, тогда не будет формальных код-ревью.
Ревьюер должен уходить от болезни "я бы сделал по-другому". Если нет чётких причин не принимать код, но хочется по-другому - прими MR и сделай по-другому.
Если ничего этого нет, тогда действительно лучше без код-ревью.
>Именно так работает потоковая сериализация, мы не строим весь объект в памяти, а записываем каждую пару ReportItem в ReportValue сразу в JSON-файл. Никаких временных словарей. Никаких temp-файлов. Только один проход и готово.
Всего кода не видно, но по описанию мне кажется, что у вас в цикле за чтением следует запись, а тут напрашивается вариант разделения чтения и записи на два потока с использованием какой-нибудь потокобезопасной очереди в качестве буфера обмена (system.threading.channels - наверное, проще всего). Интересно, принесло бы в вашем случае это какие-то существенные выгоды?
>В .NET подобные структуры данных имеют дополнительную служебную нагрузку (примерно 24 байта на элемент), а также хранят ссылки на свои элементы.
А у вас есть контроль над типами ReportItem/ReportValue? Нельзя ли там какие-то элементы уложить собственно в структуры (struct) и посмотреть, какая экономия памяти из этого получится?
А как всё это хозяйство дебажить?
Автор объясняет суть атомарности и объясняет правильно, вы же просто докапываетесь до мышей или до блох. Разумеется, в транзакции "ошибка" а-ля исключение, может быть перехвачена, а rollback может быть вызван без исключения-ошибки, на основе проверки бизнес-условий. Понятно почему автор не стал останавливаться на таких тривиальностях. Непонятно почему вы преподносите эти тривиальности с таким апломбом.
Вот эти реальные вопросы на самом деле важны, а не бесконечное пережёвывание определения REST'а по Филдингу.
А вот при неполучении результата кэшируется исключение, так что с этим паттерном надо быть осмотрительным.
Когда не следует заменять классы структурами:
В структурах есть ссылочные типы, такие как String.
А почему не надо заменять классы структурами, если в структуре есть ссылочные типы? Что плохого случится, если я заменю
record User(string Name, int Age)наreadonly record struct User(string Name, int Age)?>Итак, предположим, у нас есть класс с массивами и структура с массивами . В первом случае массивы будут храниться в оперативной памяти нашего приложения, а во втором — в кэше процессора (с учетом некоторых особенностей сборки мусора, которые мы обсудим ниже).
Судя по примерам ниже, у вас речь не про классы/структуры с массивами, а про массивы классов и структур. Так дальнейшие рассуждения приобретают рамки хоть какого-то смысла. Т.е., становится понятно, что хотел сказать автор, но смысла в сказанном всё равно остаётся не много.
1. Структуры не хранятся в оперативной памяти?
2. Структуры гарантированно находятся в кэше процессора?
3. Классы не могут помещаться в кэш процессора?
Вопросы-вопросы...
Про TryGetValue автор статьи, взявшийся писать про оптимизацию использования CPU в C# не знает?
if(cache.ContainsKey(input)) {returncache[input]; }А вот shrplab для обоих ваших вариантов с обходом цикла - и для "плохого" (где numbers[i]*numbers[i]) и для "хорошего" (где num*num) выдаёт одинаковый Asm Code.
Выходит, компилятор запросто справляется с такого рода оптимизациями...
https://sharplab.io/#v2:C4LghgzgtgPgAgJgIwFgBQcDMACR2DC2A3utmbjgJYB2w2AskgBQ3ADaAuttQK5QBGAUwBOEAJTFS5aa2wQ+2ALzYADAG50U6WQBmAe2HYWtbJSWq1p7AB5ufIaIB0AGUHUA5sAAWlygGo/CRI0bVC5BT9lXgERCDZKLgAqOxjReI4NELCAXy1tPOk4AHZwqEzpXKyyPKxTE3oEY3YuaIdxSSrtWXkoc3VNTul9QyarZXUrW1bYlzdPH1MAoIKw2WjzabSE8rDpHuxIlOxk6J3Qyt2VsmLSs+xK7KA==
Подушню: а вариант "писать меньше логов" вам не подошёл?
Обратная совместимость сломается (кто знает, какую логику вы накрутили на Add в своей реализации ILIst).
Продукт-менеджер ставит продуктовые задачи, а её декомпозицию на задачи разработчиков осуществляет тимлид. Вот он и должен принимать MR. Если на одного человека оказывается много нагрузки, а в команде достаточно сеньоров, то обязанности можно делить и тогда каждый сеньор будет "тимлидом" для своей _продуктовой_ задачи. Главное тут чтобы тот, кто проверяет MR, был глубоко погружён в проблематику общей (продуктовой) задачи, это лекарство от формальных ревью. И обычно этот человек тот, кто осуществил декомпозицию.
Отобрали?
Ещё сотовые операторы :-) Постоянно пекутся о моей выгоде.
Чтобы точно сказать надо глубже в код погружаться, на, да, предполагаю, что тут есть место переаллокациям, как при работе с List.
Вариант со stackalloc не для всякого размера строки подойдёт из-за StackOverflowException,хорошо бы про такие вещи упоминать.
Аллокацию памяти можно свести до нуля, если ввести флаг hasWhitespaces и устанавливать его в цикле при встрече пробельного символа. Тогда в случае hasWhitespaces=false можно возвращать исходную строку не создавая новую. Но осмысленность такой оптимизации зависит от контекста: как часто в рассматриваемом сценарии будут встречаться строки без пробельных символов и готовы ли вы за отсутствие аллокации в некоторых случаях платить расходом нескольких дополнительных тактов процессора в случае каждом.
В примере с буфером размер строки известен, в примере с ToArray используется итератор, ToArray в данном случае не может делать предположений о конечном размере коллекции.
P.S. Если бы ToArray к ICollection применялся, тогда другое дело, вот что у метода ToArray() под капотом.
Почему?
Запрос на ревью должен быть в приоритете у проверяющего, тогда MR не будет долго мариноваться. Если ты не можешь прервать свой "поток", тогда тебе лучше не заниматься код-ревью.
Проверять код должен тот, кто ставил задачу, тогда не будет формальных код-ревью.
Ревьюер должен уходить от болезни "я бы сделал по-другому". Если нет чётких причин не принимать код, но хочется по-другому - прими MR и сделай по-другому.
Если ничего этого нет, тогда действительно лучше без код-ревью.
>Именно так работает потоковая сериализация, мы не строим весь объект в памяти, а записываем каждую пару
ReportItemвReportValueсразу в JSON-файл. Никаких временных словарей. Никаких temp-файлов. Только один проход и готово.Всего кода не видно, но по описанию мне кажется, что у вас в цикле за чтением следует запись, а тут напрашивается вариант разделения чтения и записи на два потока с использованием какой-нибудь потокобезопасной очереди в качестве буфера обмена (system.threading.channels - наверное, проще всего). Интересно, принесло бы в вашем случае это какие-то существенные выгоды?
>В .NET подобные структуры данных имеют дополнительную служебную нагрузку (примерно 24 байта на элемент), а также хранят ссылки на свои элементы.
А у вас есть контроль над типами ReportItem/ReportValue? Нельзя ли там какие-то элементы уложить собственно в структуры (struct) и посмотреть, какая экономия памяти из этого получится?