C> int maxValue = anArray.Max();
C> int maxIndex = anArray.ToList().IndexOf(maxValue);
C>
C>198 плюсов! C>Ох ты ж б*я с*а е*й п*ц.
C>Ну и в качестве вишенки на торте: C>
C>Director/CTO at TensorStack Ltd.
Давай трезво подумаем.
Есть вариант сначала найти максимум — O(N), затем поискать его индекс — снова O(N). Итого O(N).
Есть вариант явным циклом, менее читаемый, и всё равно O(N).
При этом при ответе сказано:
This is not the most glamorous way but works.
Что не так?
Ну да, я бы ещё дописал "а если вы хотите ну совсем экономно, разверните цикл ручками". Собственно это всё, что не совсем хорошо.
PS: А зачем ты вообще пошёл искать ответ на такой вопрос? )
Здравствуйте, netch80, Вы писали:
N>При этом, если посмотреть с точки зрения процессора, первый скан погрузит массив в кэш, поэтому второй пройдёт быстрее, и будет, условно, не 2*C*N, а 1.1*C*N.
А точно второй продет быстрее, ToList ничего не "попротит"? Тот же кэш не сбросится, да и сам ToList ничего не стоит?
Здравствуйте, rFLY, Вы писали:
FLY>Здравствуйте, netch80, Вы писали:
N>>При этом, если посмотреть с точки зрения процессора, первый скан погрузит массив в кэш, поэтому второй пройдёт быстрее, и будет, условно, не 2*C*N, а 1.1*C*N. FLY>А точно второй продет быстрее, ToList ничего не "попротит"? Тот же кэш не сбросится, да и сам ToList ничего не стоит?
А, вот это не заметил. Если оно копирует, то тогда часть с кэшом меньше участвует, может оказаться, что нет. Поправлю.
Всё равно остаётся O(N), хоть и криво.
Здравствуйте, netch80, Вы писали:
N>Давай трезво подумаем. N>Есть вариант сначала найти максимум — O(N), затем поискать его индекс — снова O(N). Итого O(N). N>Есть вариант явным циклом, менее читаемый, и всё равно O(N).
Я не очень, правда, понял, зачем там массив в списек разворачивают. Какое-то лишнее телодвижение, IMHO.
C> int maxIndex = anArray.ToList().IndexOf(maxValue); C>198 плюсов! C>Ох ты ж б*я с*а е*й п*ц. C>Director/CTO at TensorStack Ltd.
Может, там массив меньше, и на то он и директор, что знает: по итогу в деньгах дешевле так?
Здравствуйте, netch80, Вы писали:
N>Всё равно остаётся O(N), хоть и криво.
А почему O(N)? Сначала пройтись по массиву, потом создать список и заново пройтись, но уже по списку.
Здравствуйте, rFLY, Вы писали:
N>>Всё равно остаётся O(N), хоть и криво. FLY>А почему O(N)? Сначала пройтись по массиву, потом создать список и заново пройтись, но уже по списку.
Ну так каждая из этих операций имеет ценой длину списка (равной длине массива).
3*O(N) тоже O(N).
Выделение памяти при схеме работы типичного дотнетовского аллокатора, скорее всего, O(1), а остальное у него размазано на другие операции.
Здравствуйте, netch80, Вы писали:
N>Ну так каждая из этих операций имеет ценой длину списка (равной длине массива). N>3*O(N) тоже O(N).
Формально так, только O более чем в 3 раза дороже в данном случае. Это же не просто взять значение из соседней ячейки, а сначала получить адрес ноды и уже потом ее значение.
C> int maxValue = anArray.Max();
C> int maxIndex = anArray.ToList().IndexOf(maxValue);
C>
C>198 плюсов! C>Ох ты ж б*я с*а е*й п*ц.
Во-во! Давно уже думаю об этом – многие люди не фильтруют ответы на SO. А то ли еще будет с ChatGPT и ему подобными... Некоторые ведь и ему безусловно доверяют. Тут-то и начнет выясняться квалификация разработчиков. А уж сколько понадобится реальных профи, чтобы исправлять потом ошибки такого начатжыпитишеного
Ну и тем не менее, лучше уж O(n), чем O(1.1n) и тем более O(2n). Да, нотация нотацией, но практически это плюс-минус в полтора раза быстрее. И да, конечно, этот кусок – песчинка во всей системе. Но если ничего не стоит написать быстрее (более быстрый код) – почему бы не воспользоваться этим
LVV>>Уровень вопроса или уровень ответа ? C>Главным образом — ответа. C>А это не очевидно?
Нет.
Сам уровень вопроса говорит о квалификции вопрошающего.
По его квалификции и дан ответ: делай так и будет работать.
Писать — мало, ошибок точно нет.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, DiPaolo, Вы писали:
DP>Но если ничего не стоит написать быстрее – почему бы не воспользоваться этим
Проблема в том, что этот ответ учит плохому начинающих. Он буквально говорит — смотри как просто, делай так. Причем предлагает как раз "гламурное" решение, хотя автор пишет об обратном. Но ужаснее всего, что это топовый ответ.
N>Что не так?
N>Ну да, я бы ещё дописал "а если вы хотите ну совсем экономно, разверните цикл ручками". Собственно это всё, что не совсем хорошо.
Дело не в двойном обходе массива, и какой там к чертям кеш — C# LINQ код такой "оптимальный" что эти понятия не существуют.
Оно создает временный List из массива — при попадании на горячий путь это поставит в неприличное положение всю софтину частыми сборками мусора.
В жизни реального приложения эти сборки приводят к переезду короткоживущих обьектов из других частей программы в старшие поколения и софтина начинает лагать и жрать процессор.