Комментарии 14
Кстати для Linq, который не делает аллокаций в куче, я писал небольшую библиотеку. Конечно, есть ограничения по сравнению с Linq (а именно - моя библиотека используется если вычисления происходят внутри метода, а последовательности никуда не передаются и не возвращаются). Список методов тут.
Вообще аналогичных либ - легион, в readme можно увидеть их сравнения, если хочется повыбирать.
В данном случае char является значимым типом, поэтому можете заменить вашу строку массивом символом.
Эммм, а ничего что массив является ссылочным типом?
Джексон Данстан написал на данную тему эту и эту статью, где демонстрирует, насколько серьезно будет отличаться производительность, если создавать ту же логику вручную.
Эти статьи от 2015 и 2018 года со "старым" фреймворком и "старой" LINQ. Надо бы провести повторные замеры.
Классический пример этого - String.Format
Жалко что автор не потрудился сказать, что делать, когда нужно отобразить "Убито 42 монстра" в UI. А решение тут простое: 3 контрола TextMeshPro + кеширование строки по ключу int.
3 контроллера вместо одного, чтобы не вызывать String.Format? Выглядит как пессимизация.
А чтобы это путёво выглядело придется еще LayoutGroup на них повесить, а это еще те тормоза, string.format отдыхает
Перебор. Есть zString или StringBuilder на худой конец
Есть возможность использовать llvm компилятор? говорят он может дать под 10-20% бонуса к производительности, а если повезет то и все +100% (если я верно понимаю, если не используются try catch, так как иначе будет хуже)
В данном случае char является значимым типом, поэтому можете заменить вашу строку массивом символом.
но разве массив символов все так же не является ссылочным типом, как и строка?
Arrays are mechanisms that allow you to treat several items as a single collection. The Microsoft® .NET Common Language Runtime (CLR) supports single-dimensional arrays, multidimensional arrays, and jagged arrays (arrays of arrays). All array types are implicitly derived from System.Array, which itself is derived from System.Object. This means that all arrays are always reference types which are allocated on the managed heap, and your app's variable contains a reference to the array and not the array itself.
https://docs.microsoft.com/en-us/archive/msdn-magazine/2002/february/net-array-types-in-net
Меня всегда интересовало зачем взяли такой тяжеловесный язык как C# в качестве скриптового языка для игрового движка, когда можно было взять что-то более простое вроде Lua или Python. С одной стороны понятно что можно использовать библиотеки из мира C# но вот читая такие статьи у меня складывается впечатление что разработчики библиотек могут и не знать о таких нюансах и вовсю использовать linq, foreach и прочие влияющие на производительность вещи. А с другой стороны если для него надо писать "свой" Linq и бороться за каждую сборку мусора то стоит ли игра свеч?
>Меня всегда интересовало зачем взяли такой тяжеловесный язык как C#
Затем, кто сообщество C# в десятки раз крупнее чем у какого-нибудь lua. Первые версии unity поддерживали java script, c#, lua и собственный скриптовый язык и поняли что люди используют только C#, а остальное выпилили.
Думаешь питон как скриптовый язык для игр это хорошая идея?))
Будто пользователи питона вкурсе как работают внутри другие пакеты. Там все намного хуже и Linq на их фоне хорош.
О недостатках FindObjectsOfType мы поговорим позже, но конкретно в данном случае мы вызываем функцию, которая и так является медленной, а также создаем новый массив всякий раз, когда вызывается OnTriggerEnter. Простой вариант оптимизации – кэшировать массив.
Но это неверный код. Вы кешируйте коллайдеры при старте, а тригер может сработать через час, когда уже эти коллайдеры 100 раз могут добавиться/удалиться.
Хотя, циклы foreach уже не так плохи, как когда-то, на самых жарких участках кода все равно стоит предпочитать стандартные циклы for циклам foreach. В Unity есть IL2CPP, что может дополнительно усугубить проблему.
Экономия на спичках. Там где жаркий участок кода, оверхед на foreach будет ещё меньше относительно самого кода. Без конкретных цифр, все эти экономии на foreach пустая трата времени и сил и типичный пример преждевременной оптимизации.
Свойства
Хотя, свойства удобно читать, есть мнение, что все свойства нужно превращать в публичные переменные. Да, может быть преподаватель на паре по информатике и наорет на вас за такое, но есть случаи, в которых чистые публичные переменные пойдут вполне нормально.
Например, нет никаких причин делать:
public int TheNumber { set; get; }
а не:
public int TheNumber;
Когда же потребуется обеспечить производительность на сложном участке, второй код будет быстрее.
Опять экономия на спичках. Насколько код будет быстрее? Уверен что такое невозможно будет измерить. Но плюсов от свойств гораздо больше. Например можно сделать отложенное кеширование переменных, добавить какую-то логику не переписывая код и не сбрасывая сереализованные переменные из редактора юнити. В конце концов, гораздо чаще требуется оставить переменную только для чтения извне.
Производительность Unity C#: советы и приемы