Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Производительность
Unity3D:
подводные камни
Алексей Чубарь, BIT.GAMES
Unity3D
Рендеринг
Анимации
Звук
Физика
Редактор
Оптимизация
…
Unity3D
Unity3D
Unity3D
Unity3D
9 FPS
ШМЯК, БРЯК
И В ПРОДАКШН
Unity3D
PC & Console games Mobile games
Architectural visualizations
Medical simulations
Military simulations
CAD
Research
Interactive presentations
…
Education
Media & movies
Art installations
Unity3D
PC & Console games Mobile games
Architectural visualizations
Medical simulations
Military simulations
CAD
Research
Interactive presentations
…
Education
Media & movies
Art installations
Суровый мир мобильных игр
Суровый мир мобильных игр
• Высокая конкуренция
Суровый мир мобильных игр
• Высокая конкуренция
• Специфика аудитории
Суровый мир мобильных игр
• Высокая конкуренция
• Специфика аудитории
• Специфика программно-аппаратной платформы
Что там внутри?
• Какой-то странный процессор
• ARM, x86, MIPS… 32 и 64 bit.
• Какой-то странный процессор
• ARM, x86, MIPS… 32 и 64 bit.
Что там внутри?
≠
Что там внутри?
• Какая-то батарейка
Что там внутри?
• Какой-то графический ускоритель
≠
Что там внутри?
• Какая-то оперативная память
• Её всегда мало
Зоопарк устройств
Зоопарк устройств
240 MB
ought to be enough for anyone – Gill Bates
• Падение FPS.
• Чёрные квадраты вместо текстур.
• «Тихое» завершение приложения без отчёта об ошибке.
Зоопарк устройств
>240 MB
Главный совет
“Make optimization a design consideration, not a final step”
- Unity Docs
Главный совет
“Make optimization a design consideration, not a final step”
- Unity Docs
Постоянно спрашивай себя: “А не ерунду ли я сейчас делаю?”
- Примерный перевод
Из-за чего всё тормозит?
Из-за чего всё тормозит?
• Код
Из-за чего всё тормозит?
• Код • Ресурсы
Импорт ресурсов
Импорт ресурсов: звук
Импорт ресурсов: звук
16 bit * 44100 Hz * 2 channels = 176.4 KB/s
Импорт ресурсов: звук
16 bit * 44100 Hz * 2 channels = 176.4 KB/s
Импорт ресурсов: звук
• Сжатие MP3 на iOS
• Сжатие Vorbis на Android
• Force Mono
• Низкий битрейт (насколько возможно)
≠
Импорт ресурсов: анимации
Импорт ресурсов: анимации
• Сложные анимации занимают много памяти. KISS.
Импорт ресурсов: анимации
• Сложные анимации занимают много памяти. KISS.
• Анимация большого числа объектов нагружает ЦП.
Импорт ресурсов: анимации
• Сложные анимации занимают много памяти. KISS.
• Анимация большого числа объектов нагружает ЦП.
• Можно уменьшить количество объектов.
Импорт ресурсов: анимации
• Сложные анимации занимают много памяти. KISS.
• Анимация большого числа объектов нагружает ЦП.
• Можно уменьшить количество объектов.
• Можно упростить объекты.
?!
Импорт ресурсов: 3D-модели
• Отключите Read/Write.
• Много полигонов = много памяти.
• Optimize Mesh Data.
Импорт ресурсов: 3D-модели
Точно ли это всё понадобится?
Импорт ресурсов: текстуры
• Сжатие обязательно
Android: ETC iOS: PVRTC
Импорт ресурсов: текстуры
RGB ETC 4 bit,
1024х1024: 512KB
RGBA 32 bit,
1024х1024: 4MB
Alpha ETC 4 bit,
512x512: 128KB
-84%
Импорт ресурсов: текстуры
RGB ETC 4 bit,
1024х1024: 512KB
RGBA 32 bit,
1024х512: 2MB
Alpha ETC 4 bit,
512x512: 128KB
-69%
• Не включайте Read/Write.
• Отключите mipmaps, если возможно.
• Не используйте огромные текстуры.
• 2048x2048 или 1024x1024 для UI
• 512x512 или меньше для текстур моделей
Импорт ресурсов: текстуры
*Допустимо, если есть запас производительности GPU
-50%
-33%*
Fillrate & overdraw
OK
Overdrawn
Борьба с overdraw
High-res
background parts
Lower-res
RenderTexture
High-DPI Device
Борьба с overdraw
High-res
background parts
Lower-res
RenderTexture
High-DPI Device
Можно переиспользовать,
если камера не движется
Борьба с overdraw
Нагрузка на GPU ниже,
когда камера статична
Код и runtime
Код и runtime
C# code
JS code
UnityScript
code
CIL
CIL
CIL
Assembly.dll
Sources Script compiler Mono runtime
JIT
AOT
Код и runtime
C# code
JS code
UnityScript
code
CIL
CIL
CIL
Assembly.dll
Sources Script compiler Mono runtime
JIT
AOT
Код и runtime
• Сборка мусора работает плохо.
• Heap удваивается при достижении лимита. И не уменьшается никогда.
• Производительность игры со временем снижается.
Код и runtime: Garbage collection
ReferenceType
class Entry {
uint id;
long phone;
string name;
}
Thread stack (FAST)
var e1 = new Entry();
var e2 = e1;
Managed heap (SLOW)
ref1
Entry
id: 1337
phone: 88005553535
name: ref2
String
value: “Ayy Lmao”
ref3
Код и runtime: Garbage collection
ValueType
struct Entry {
uint id;
long phone;
string name;
}
Thread stack (FAST)
var e1 = new Entry();
var e2 = e1;
Managed heap (SLOW)
Entry
id: 1337
phone: 88005553535
name: ref1
String
value: “Ayy Lmao”
Entry (сopy)
id: 740
phone: 88005553535
name: ref2e2.id = 740;
Код и runtime: аллокации
• ValueType вместо ReferenceType, где уместно.
Код и runtime: аллокации
• ValueType вместо ReferenceType, где уместно.
• Меньше временных объектов, аллоцируй однажды и переиспользуй.
Код и runtime: аллокации
Refactor
public static class Modifiers
{
public List<Modifier> GetAll()
{
var tmp = new List<Modifier>();
FillStuff(tmp);
return tmp;
}
}
public static class Modifiers
{
public void GetAll(List<Modifier> to_fill)
{
to_fill.Clear();
FillStuff(to_fill);
}
}
public void Update()
{
List<Modifier> modifiers = Modifiers.GetAll();
DisplayModifiers(modifiers);
}
List<Modifier> = new List<Modifier>(CAPACITY);
public void Update()
{
Modifiers.GetAll(modifiers);
DisplayModifiers(modifiers);
}
Код и runtime: аллокации
• ValueType вместо ReferenceType, где уместно.
• Меньше временных объектов, аллоцируй однажды и переиспользуй.
• «Гибридные» контейнеры.
Код и runtime: аллокации
struct HList<T> : IList<T>
гибридный контейнер
T val0;
T val1;
T val2;
T val3;
List<T> fallback; T TT ...
myHList.Add(newVal);
Count >
Capacity?
True,
alloc fallback once
False,
no allocs
Код и runtime: неявные аллокации
• Regex;
Код и runtime: неявные аллокации
• Regex;
• “Excessive” + “ strings “ + “concat”;
Код и runtime: неявные аллокации
• Regex;
• “Excessive” + “ strings “ + “concat”;
• Closures & anon methods;
public void LoginWithID(int id)
{
if(IsLoggedIn())
return;
LoginWithDelegate(
delegate() { ProcessNewID(id); }
);
}
Вы ещё здесь…
… а эти объекты
уже созданы в heap.
“id” используется в closure,
копия создаётся в heap.
Код и runtime: неявные аллокации
• Regex;
• “Excessive” + “ strings “ + “concat”;
• Closures & anon methods;
• LINQ;
Код и runtime: неявные аллокации
• Regex;
• “Excessive” + “ strings “ + “concat”;
• Closures & anon methods;
• LINQ;
• foreach;
Код и runtime: неявные аллокации
• Regex;
• “Excessive” + “ strings “ + “concat”;
• Closures & anon methods;
• LINQ;
• foreach;
• using;
Код и runtime: неявные аллокации
• Regex;
• “Excessive” + “ strings “ + “concat”;
• Closures & anon methods;
• LINQ;
• foreach;
• using;
• Array.IndexOf и т.п.;
• …
Код и runtime: boxing
struct Entry : IPrintable
Thread stack
var e1 = new Entry();
Entry
Managed heapvoid MyPrint(IPrintable p)
Object (boxed Entry)
IPrintable toPrint = e1;
MyPrint(toPrint); IPrintable ref1
Неявная аллокация
Код и runtime: аллокации Unity API
SkinnedMeshRenderer smr = ...;
for(int i = 0; i < smr.bones.Length; i++)
{
//... Do stuff
}
SkinnedMeshRenderer smr = ...;
var bones = smr.bones;
for(int i = 0; i < bones.Length; i++)
{
//... Do stuff
}
Код и runtime: аллокации Unity API
SkinnedMeshRenderer smr = ...;
for(int i = 0; i < smr.bones.Length; i++)
{
//... Do stuff
}
SkinnedMeshRenderer smr = ...;
var bones = smr.bones;
for(int i = 0; i < bones.Length; i++)
{
//... Do stuff
}
Аллоцирует массив “bones”
bones.Length раз
Аллоцирует массив “bones”
1 раз
Код и runtime: аллокации Unity API
• Если Unity API возвращает массив, будет создана новая копия.
Код и runtime: аллокации Unity API
• Если Unity API возвращает массив, будет создана новая копия.
• Каждый раз.
Код и runtime: аллокации Unity API
• Если Unity API возвращает массив, будет создана новая копия.
• Каждый раз.
• Даже если значение не изменилось.
Код и runtime: аллокации Unity API
• Если Unity API возвращает массив, будет создана новая копия.
• Каждый раз.
• Даже если значение не изменилось.
• Даже если это выглядит как безобидный getter.
Код и runtime: аллокации Unity API
• Если Unity API возвращает массив, будет создана новая копия.
• Каждый раз.
• Даже если значение не изменилось.
• Даже если это выглядит как безобидный getter.
• «Безобидный getter» может скрывать внутри тяжёлые вычисления.
public string name {
get {
return BadWordsFilter.ReplaceAll(data.name.Unescape());
}
}
Код и runtime: прочее
• No inlining.
• Вызов метода С# = вызов в машинном коде.
• Property accessors = вызов метода.
• Это сказывается на скорости интенсивных вычислений.
• Do inlining yourself.
Код и runtime: прочее
• К свойствам некоторых компонентов можно обращаться по
имени (Animator, Shader, Material).
• Внутри имя каждый раз преобразовывается в хэш.
• Вычисли хэш однажды и переиспользуй.
material.SetColor(“_Color”, Color.white);
animator.SetTrigger(“attack”);
static readonly int HASH_MAT_COLOR = Shader.PropertyToID(“_Color”);
static readonly int HASH_ANIM_ATTACK = Animator.StringToHash(“attack”);
material.SetColor(HASH_MAT_COLOR, Color.white);
animator.SetTrigger(HASH_ANIM_ATTACK);
Код и runtime: прочее
• Reflection is slow.
• Text parsing is slow.
• Text parsers based on Reflection are super slow.
Профайлинг
Профайлинг
• Встроенный профайлер Unity.
Профайлинг
• Встроенный профайлер Unity.
• XCode Instruments.
Профайлинг
Скорость
итераций
Сложность
интерпретации
Точность
Поддержка
ОС
Unity
(редактор)
Очень
высокая
Низкая Низкая -
Unity
(устройство)
Низкая Низкая Средняя Любая
XCode
Instruments
Низкая Средняя
Очень
высокая
Только iOS
Профайлинг
140.1 MB
Unity
Профайлинг: Unity врёт
140.1 MB
262.0 MB
Unity
XCode
Профайлинг: Unity врёт
140.1 MB
262.0 MB
Unity
XCode
Summary
• Специфика мобильных платформ должна учитываться на всех этапах
разработки.
Summary
• Специфика мобильных платформ должна учитываться на всех этапах
разработки.
• Экономить RAM не менее важно, чем ресурс CPU и GPU.
Summary
• Специфика мобильных платформ должна учитываться на всех этапах
разработки.
• Экономить RAM не менее важно, чем ресурс CPU и GPU.
• Разумный компромисс «Качество vs. Память» для ассетов, сжатие.
Summary
• Специфика мобильных платформ должна учитываться на всех этапах
разработки.
• Экономить RAM не менее важно, чем ресурс CPU и GPU.
• Разумный компромисс «Качество vs. Память» для ассетов, сжатие.
• Избегай overdraw.
Summary
• Специфика мобильных платформ должна учитываться на всех этапах
разработки.
• Экономить RAM не менее важно, чем ресурс CPU и GPU.
• Разумный компромисс «Качество vs. Память» для ассетов, сжатие.
• Избегай overdraw.
• Избегай аллокаций и boxing’а.
Summary
• Специфика мобильных платформ должна учитываться на всех этапах
разработки.
• Экономить RAM не менее важно, чем ресурс CPU и GPU.
• Разумный компромисс «Качество vs. Память» для ассетов, сжатие.
• Избегай overdraw.
• Избегай аллокаций и boxing’а.
• Помни особенности Unity Mono Runtime. («heap never shrinks»)
Summary
• Специфика мобильных платформ должна учитываться на всех этапах
разработки.
• Экономить RAM не менее важно, чем ресурс CPU и GPU.
• Разумный компромисс «Качество vs. Память» для ассетов, сжатие.
• Избегай overdraw.
• Избегай аллокаций и boxing’а.
• Помни особенности Unity Mono Runtime. («heap never shrinks»)
• Помни особенности Unity API. («no inlining», «arrays always allocated»)
Summary
• Специфика мобильных платформ должна учитываться на всех этапах
разработки.
• Экономить RAM не менее важно, чем ресурс CPU и GPU.
• Разумный компромисс «Качество vs. Память» для ассетов, сжатие.
• Избегай overdraw.
• Избегай аллокаций и boxing’а.
• Помни особенности Unity Mono Runtime. («heap never shrinks»)
• Помни особенности Unity API. («no inlining», «arrays always allocated»)
• Профайлить надо. Часто. Через Instruments.
Спасибо за внимание

More Related Content

Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

  • 7. Unity3D PC & Console games Mobile games Architectural visualizations Medical simulations Military simulations CAD Research Interactive presentations … Education Media & movies Art installations
  • 8. Unity3D PC & Console games Mobile games Architectural visualizations Medical simulations Military simulations CAD Research Interactive presentations … Education Media & movies Art installations
  • 10. Суровый мир мобильных игр • Высокая конкуренция
  • 11. Суровый мир мобильных игр • Высокая конкуренция • Специфика аудитории
  • 12. Суровый мир мобильных игр • Высокая конкуренция • Специфика аудитории • Специфика программно-аппаратной платформы
  • 13. Что там внутри? • Какой-то странный процессор • ARM, x86, MIPS… 32 и 64 bit.
  • 14. • Какой-то странный процессор • ARM, x86, MIPS… 32 и 64 bit. Что там внутри? ≠
  • 15. Что там внутри? • Какая-то батарейка
  • 16. Что там внутри? • Какой-то графический ускоритель ≠
  • 17. Что там внутри? • Какая-то оперативная память • Её всегда мало
  • 19. Зоопарк устройств 240 MB ought to be enough for anyone – Gill Bates
  • 20. • Падение FPS. • Чёрные квадраты вместо текстур. • «Тихое» завершение приложения без отчёта об ошибке. Зоопарк устройств >240 MB
  • 21. Главный совет “Make optimization a design consideration, not a final step” - Unity Docs
  • 22. Главный совет “Make optimization a design consideration, not a final step” - Unity Docs Постоянно спрашивай себя: “А не ерунду ли я сейчас делаю?” - Примерный перевод
  • 23. Из-за чего всё тормозит?
  • 24. Из-за чего всё тормозит? • Код
  • 25. Из-за чего всё тормозит? • Код • Ресурсы
  • 28. Импорт ресурсов: звук 16 bit * 44100 Hz * 2 channels = 176.4 KB/s
  • 29. Импорт ресурсов: звук 16 bit * 44100 Hz * 2 channels = 176.4 KB/s
  • 30. Импорт ресурсов: звук • Сжатие MP3 на iOS • Сжатие Vorbis на Android • Force Mono • Низкий битрейт (насколько возможно) ≠
  • 32. Импорт ресурсов: анимации • Сложные анимации занимают много памяти. KISS.
  • 33. Импорт ресурсов: анимации • Сложные анимации занимают много памяти. KISS. • Анимация большого числа объектов нагружает ЦП.
  • 34. Импорт ресурсов: анимации • Сложные анимации занимают много памяти. KISS. • Анимация большого числа объектов нагружает ЦП. • Можно уменьшить количество объектов.
  • 35. Импорт ресурсов: анимации • Сложные анимации занимают много памяти. KISS. • Анимация большого числа объектов нагружает ЦП. • Можно уменьшить количество объектов. • Можно упростить объекты. ?!
  • 36. Импорт ресурсов: 3D-модели • Отключите Read/Write. • Много полигонов = много памяти. • Optimize Mesh Data.
  • 37. Импорт ресурсов: 3D-модели Точно ли это всё понадобится?
  • 38. Импорт ресурсов: текстуры • Сжатие обязательно Android: ETC iOS: PVRTC
  • 39. Импорт ресурсов: текстуры RGB ETC 4 bit, 1024х1024: 512KB RGBA 32 bit, 1024х1024: 4MB Alpha ETC 4 bit, 512x512: 128KB -84%
  • 40. Импорт ресурсов: текстуры RGB ETC 4 bit, 1024х1024: 512KB RGBA 32 bit, 1024х512: 2MB Alpha ETC 4 bit, 512x512: 128KB -69%
  • 41. • Не включайте Read/Write. • Отключите mipmaps, если возможно. • Не используйте огромные текстуры. • 2048x2048 или 1024x1024 для UI • 512x512 или меньше для текстур моделей Импорт ресурсов: текстуры *Допустимо, если есть запас производительности GPU -50% -33%*
  • 43. Борьба с overdraw High-res background parts Lower-res RenderTexture High-DPI Device
  • 44. Борьба с overdraw High-res background parts Lower-res RenderTexture High-DPI Device Можно переиспользовать, если камера не движется
  • 45. Борьба с overdraw Нагрузка на GPU ниже, когда камера статична
  • 47. Код и runtime C# code JS code UnityScript code CIL CIL CIL Assembly.dll Sources Script compiler Mono runtime JIT AOT
  • 48. Код и runtime C# code JS code UnityScript code CIL CIL CIL Assembly.dll Sources Script compiler Mono runtime JIT AOT
  • 49. Код и runtime • Сборка мусора работает плохо. • Heap удваивается при достижении лимита. И не уменьшается никогда. • Производительность игры со временем снижается.
  • 50. Код и runtime: Garbage collection ReferenceType class Entry { uint id; long phone; string name; } Thread stack (FAST) var e1 = new Entry(); var e2 = e1; Managed heap (SLOW) ref1 Entry id: 1337 phone: 88005553535 name: ref2 String value: “Ayy Lmao” ref3
  • 51. Код и runtime: Garbage collection ValueType struct Entry { uint id; long phone; string name; } Thread stack (FAST) var e1 = new Entry(); var e2 = e1; Managed heap (SLOW) Entry id: 1337 phone: 88005553535 name: ref1 String value: “Ayy Lmao” Entry (сopy) id: 740 phone: 88005553535 name: ref2e2.id = 740;
  • 52. Код и runtime: аллокации • ValueType вместо ReferenceType, где уместно.
  • 53. Код и runtime: аллокации • ValueType вместо ReferenceType, где уместно. • Меньше временных объектов, аллоцируй однажды и переиспользуй.
  • 54. Код и runtime: аллокации Refactor public static class Modifiers { public List<Modifier> GetAll() { var tmp = new List<Modifier>(); FillStuff(tmp); return tmp; } } public static class Modifiers { public void GetAll(List<Modifier> to_fill) { to_fill.Clear(); FillStuff(to_fill); } } public void Update() { List<Modifier> modifiers = Modifiers.GetAll(); DisplayModifiers(modifiers); } List<Modifier> = new List<Modifier>(CAPACITY); public void Update() { Modifiers.GetAll(modifiers); DisplayModifiers(modifiers); }
  • 55. Код и runtime: аллокации • ValueType вместо ReferenceType, где уместно. • Меньше временных объектов, аллоцируй однажды и переиспользуй. • «Гибридные» контейнеры.
  • 56. Код и runtime: аллокации struct HList<T> : IList<T> гибридный контейнер T val0; T val1; T val2; T val3; List<T> fallback; T TT ... myHList.Add(newVal); Count > Capacity? True, alloc fallback once False, no allocs
  • 57. Код и runtime: неявные аллокации • Regex;
  • 58. Код и runtime: неявные аллокации • Regex; • “Excessive” + “ strings “ + “concat”;
  • 59. Код и runtime: неявные аллокации • Regex; • “Excessive” + “ strings “ + “concat”; • Closures & anon methods; public void LoginWithID(int id) { if(IsLoggedIn()) return; LoginWithDelegate( delegate() { ProcessNewID(id); } ); } Вы ещё здесь… … а эти объекты уже созданы в heap. “id” используется в closure, копия создаётся в heap.
  • 60. Код и runtime: неявные аллокации • Regex; • “Excessive” + “ strings “ + “concat”; • Closures & anon methods; • LINQ;
  • 61. Код и runtime: неявные аллокации • Regex; • “Excessive” + “ strings “ + “concat”; • Closures & anon methods; • LINQ; • foreach;
  • 62. Код и runtime: неявные аллокации • Regex; • “Excessive” + “ strings “ + “concat”; • Closures & anon methods; • LINQ; • foreach; • using;
  • 63. Код и runtime: неявные аллокации • Regex; • “Excessive” + “ strings “ + “concat”; • Closures & anon methods; • LINQ; • foreach; • using; • Array.IndexOf и т.п.; • …
  • 64. Код и runtime: boxing struct Entry : IPrintable Thread stack var e1 = new Entry(); Entry Managed heapvoid MyPrint(IPrintable p) Object (boxed Entry) IPrintable toPrint = e1; MyPrint(toPrint); IPrintable ref1 Неявная аллокация
  • 65. Код и runtime: аллокации Unity API SkinnedMeshRenderer smr = ...; for(int i = 0; i < smr.bones.Length; i++) { //... Do stuff } SkinnedMeshRenderer smr = ...; var bones = smr.bones; for(int i = 0; i < bones.Length; i++) { //... Do stuff }
  • 66. Код и runtime: аллокации Unity API SkinnedMeshRenderer smr = ...; for(int i = 0; i < smr.bones.Length; i++) { //... Do stuff } SkinnedMeshRenderer smr = ...; var bones = smr.bones; for(int i = 0; i < bones.Length; i++) { //... Do stuff } Аллоцирует массив “bones” bones.Length раз Аллоцирует массив “bones” 1 раз
  • 67. Код и runtime: аллокации Unity API • Если Unity API возвращает массив, будет создана новая копия.
  • 68. Код и runtime: аллокации Unity API • Если Unity API возвращает массив, будет создана новая копия. • Каждый раз.
  • 69. Код и runtime: аллокации Unity API • Если Unity API возвращает массив, будет создана новая копия. • Каждый раз. • Даже если значение не изменилось.
  • 70. Код и runtime: аллокации Unity API • Если Unity API возвращает массив, будет создана новая копия. • Каждый раз. • Даже если значение не изменилось. • Даже если это выглядит как безобидный getter.
  • 71. Код и runtime: аллокации Unity API • Если Unity API возвращает массив, будет создана новая копия. • Каждый раз. • Даже если значение не изменилось. • Даже если это выглядит как безобидный getter. • «Безобидный getter» может скрывать внутри тяжёлые вычисления. public string name { get { return BadWordsFilter.ReplaceAll(data.name.Unescape()); } }
  • 72. Код и runtime: прочее • No inlining. • Вызов метода С# = вызов в машинном коде. • Property accessors = вызов метода. • Это сказывается на скорости интенсивных вычислений. • Do inlining yourself.
  • 73. Код и runtime: прочее • К свойствам некоторых компонентов можно обращаться по имени (Animator, Shader, Material). • Внутри имя каждый раз преобразовывается в хэш. • Вычисли хэш однажды и переиспользуй. material.SetColor(“_Color”, Color.white); animator.SetTrigger(“attack”); static readonly int HASH_MAT_COLOR = Shader.PropertyToID(“_Color”); static readonly int HASH_ANIM_ATTACK = Animator.StringToHash(“attack”); material.SetColor(HASH_MAT_COLOR, Color.white); animator.SetTrigger(HASH_ANIM_ATTACK);
  • 74. Код и runtime: прочее • Reflection is slow. • Text parsing is slow. • Text parsers based on Reflection are super slow.
  • 82. Summary • Специфика мобильных платформ должна учитываться на всех этапах разработки.
  • 83. Summary • Специфика мобильных платформ должна учитываться на всех этапах разработки. • Экономить RAM не менее важно, чем ресурс CPU и GPU.
  • 84. Summary • Специфика мобильных платформ должна учитываться на всех этапах разработки. • Экономить RAM не менее важно, чем ресурс CPU и GPU. • Разумный компромисс «Качество vs. Память» для ассетов, сжатие.
  • 85. Summary • Специфика мобильных платформ должна учитываться на всех этапах разработки. • Экономить RAM не менее важно, чем ресурс CPU и GPU. • Разумный компромисс «Качество vs. Память» для ассетов, сжатие. • Избегай overdraw.
  • 86. Summary • Специфика мобильных платформ должна учитываться на всех этапах разработки. • Экономить RAM не менее важно, чем ресурс CPU и GPU. • Разумный компромисс «Качество vs. Память» для ассетов, сжатие. • Избегай overdraw. • Избегай аллокаций и boxing’а.
  • 87. Summary • Специфика мобильных платформ должна учитываться на всех этапах разработки. • Экономить RAM не менее важно, чем ресурс CPU и GPU. • Разумный компромисс «Качество vs. Память» для ассетов, сжатие. • Избегай overdraw. • Избегай аллокаций и boxing’а. • Помни особенности Unity Mono Runtime. («heap never shrinks»)
  • 88. Summary • Специфика мобильных платформ должна учитываться на всех этапах разработки. • Экономить RAM не менее важно, чем ресурс CPU и GPU. • Разумный компромисс «Качество vs. Память» для ассетов, сжатие. • Избегай overdraw. • Избегай аллокаций и boxing’а. • Помни особенности Unity Mono Runtime. («heap never shrinks») • Помни особенности Unity API. («no inlining», «arrays always allocated»)
  • 89. Summary • Специфика мобильных платформ должна учитываться на всех этапах разработки. • Экономить RAM не менее важно, чем ресурс CPU и GPU. • Разумный компромисс «Качество vs. Память» для ассетов, сжатие. • Избегай overdraw. • Избегай аллокаций и boxing’а. • Помни особенности Unity Mono Runtime. («heap never shrinks») • Помни особенности Unity API. («no inlining», «arrays always allocated») • Профайлить надо. Часто. Через Instruments.