|
Unity Мультиплатформенный инструмент для разработки игр |
20.08.2016, 07:36
|
#1
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Decompiled Unity5.3 (c#)
Декомпиленные исходники шарповской части юнити5.3
ссылка на гитхаб
Как и ожидалось, почти весь код - это врапперы над c++ ядром.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо Жека за это полезное сообщение:
|
|
20.08.2016, 07:54
|
#2
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Зацените функцию:
[TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] public static Object FindObjectOfType(Type type) { Object[] objArray = FindObjectsOfType(type); if (objArray.Length > 0) { return objArray[0]; } return null; }
выгребаются все объекты и берётся первый. как-то расточительно.
|
(Offline)
|
|
Эти 3 пользователя(ей) сказали Спасибо Жека за это полезное сообщение:
|
|
20.08.2016, 17:22
|
#3
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
А вот кастинг типа при каждой установке свойства в классе Transform
public Transform parent { get { return this.parentInternal; } set { if (this is RectTransform) { Debug.LogWarning("Parent of RectTransform is being set with parent property. Consider using the SetParent method instead, with the worldPositionStays argument set to false. This will retain local orientation and scale rather than world orientation and scale, which can prevent common UI scaling issues.", this); } this.parentInternal = value; } }
Почему бы в сеттер не воткнуть SetParent.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
20.08.2016, 20:07
|
#4
|
Ференька
Регистрация: 26.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,742
Написано 5,461 полезных сообщений (для 15,675 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Сообщение от Жека
Зацените функцию:
[TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
public static Object FindObjectOfType(Type type)
{
Object[] objArray = FindObjectsOfType(type);
if (objArray.Length > 0)
{
return objArray[0];
}
return null;
}
выгребаются все объекты и берётся первый. как-то расточительно.
|
Спасибо! Теперь буду знать, что это не дешевле чем взять всё.
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**
* — в стадии разработки
** — в стадии проектирования
Для проектов в стадии проектирования приведены кодовые имена
|
(Offline)
|
|
21.08.2016, 11:38
|
#5
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Все предустановленные направления вектора реализованы так:
public static Vector2 zero { get { return new Vector2(0f, 0f); } } public static Vector2 one { get { return new Vector2(1f, 1f); } }
Каждый раз создаётся новый вектор. Наверное для стэковой памяти это не затратно.
Хотя я читал, что при присвоении типа struct в переменную создается копия. Получается, тут будет дважды создана копия:
Или нет?
|
(Offline)
|
|
21.08.2016, 11:47
|
#6
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Ещё стал интесесен вопрос юзания оператора foreach. На каждый форыч создаётся новый объект-итератор.
Если не предполагается пробегать по той же коллекции внутри другого форыча, то можно бы сделать кэшированный итератор, для которого вместо new будет вызываться iterator.reset (this) - сбрасываем индекс в ноль или ссылку на first.
В манки-юнити хочу сделать такой кэш-вариант для списков, которые не торчат наружу в юзерский код.
|
(Offline)
|
|
21.08.2016, 12:08
|
#7
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Теперь буду знать, что это не дешевле чем взять всё.
|
А где эта функция нужна?
Я не встречал, вроде - ни в проектах, ни в других файлах исходников.
|
(Offline)
|
|
22.08.2016, 20:06
|
#8
|
Бывалый
Регистрация: 19.06.2008
Сообщений: 679
Написано 264 полезных сообщений (для 450 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Сообщение от Жека
Все предустановленные направления вектора реализованы так:
public static Vector2 zero
{
get
{
return new Vector2(0f, 0f);
}
}
public static Vector2 one
{
get
{
return new Vector2(1f, 1f);
}
}
Каждый раз создаётся новый вектор. Наверное для стэковой памяти это не затратно.
Хотя я читал, что при присвоении типа struct в переменную создается копия. Получается, тут будет дважды создана копия:
Или нет?
|
Нет, не будет.
Все правильно читал - значимые типы в дотнете "копируются" при присвоении. Однако в приведенном тобой примере есть только 1 присвоение. Есть 2 причины почему здесь не будет "двойного" копирования.
Причина 1:
Есть код
var vector = new Vector3(1, 2, 3);
В этом месте будет сгенерирован такой код что значения 1, 2 и 3 будут тупо инструкцией mov скопированы на соответствующие участки памяти на стеке (то есть в переменную vector)
Другой код
var vector = Vector3.Zero;
...
public static Vector3 Zero {
get {
return new Vector3(1, 2, 3);
}
}
В этом коде надо сначала создать вектор а потом "вернуть" его. Но дважды ничего копировать не придется и вот почему: вызывающая функция знает что возвращенное значение придется куда-то сохранить, поэтому она передает методу (а геттер это просто метод, на самом деле) аргумент (в каком-то из регистров) - указатель на локальную переменную vector то есть куда именно геттеру надо записать "созданный" вектор. То есть метод сразу пишет куда надо и только 1 раз. Это первая причина почему "двойного" копирования нет.
Причина 2:
Из-за того что геттер Vector3.Zero довольно простой и мал в размере, он 99% будет заинлайнен, так что
var vector = new Vector(0, 0, 0);
и
var vector = Vector3.Zero;
это одно и тоже.
__________________
|
(Offline)
|
|
Эти 6 пользователя(ей) сказали Спасибо h1dd3n за это полезное сообщение:
|
|
22.08.2016, 20:19
|
#9
|
Бывалый
Регистрация: 19.06.2008
Сообщений: 679
Написано 264 полезных сообщений (для 450 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Сообщение от Жека
Ещё стал интесесен вопрос юзания оператора foreach. На каждый форыч создаётся новый объект-итератор.
Если не предполагается пробегать по той же коллекции внутри другого форыча, то можно бы сделать кэшированный итератор, для которого вместо new будет вызываться iterator.reset (this) - сбрасываем индекс в ноль или ссылку на first.
В манки-юнити хочу сделать такой кэш-вариант для списков, которые не торчат наружу в юзерский код.
|
Да, итератор создается каждый раз. Но это совершенно ничего не значит. Создание объекта ничего не стоит. Да, серьезно, ничего не стоит. Аллокация памяти в дотнете нереально быстрая (как и в яве, например), ибо память то уже аллоцирована одним большим куском. Вот когда сборщик мусора начинает работать, то огромное кол-во объектов может стать для него проблемой. Но речь идет о десятках гигабайт и миллиардах объектов в секунду. К тому же аллокация и сборщик работают только на ссылочных типах, значимые то хранятся на стеке. Память то там не аллоцируется, и сборщик потом такие объекты не собирает. И итератор такой распостраненной коллекции как List<T>, например, объявлен как struct, а значит вся эта фигня с кешированием ничего не даст.
http://referencesource.microsoft.com...661cf752ff3f44
__________________
|
(Offline)
|
|
Эти 3 пользователя(ей) сказали Спасибо h1dd3n за это полезное сообщение:
|
|
22.08.2016, 21:04
|
#10
|
Бывалый
Регистрация: 19.06.2008
Сообщений: 679
Написано 264 полезных сообщений (для 450 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Добавлю
var vector = new Vector2(0, 0);
000007FF001735A4 xor eax,eax
000007FF001735A6 mov qword ptr [rsp+20h],rax
Без инлайнинга ([MethodImpl(MethodImplOptions.NoInlining)]):
var vector = Vector2.Zero;
000007FF0019348E call 000007FF0005C940
000007FF00193493 mov qword ptr [rsp+28h],rax
Здесь в rax - вся структура (8 байт). Код был бы немного другим если бы структура не влезала в регистр целиком:
Это код геттера для Vector3
000007FE7F9D4670 vxorps xmm0,xmm0,xmm0
000007FE7F9D4675 vxorps xmm1,xmm1,xmm1
000007FE7F9D467A vmovss dword ptr [rcx],xmm0
000007FE7F9D467F vmovss dword ptr [rcx+4],xmm1
000007FE7F9D4685 vmovss dword ptr [rcx+8],xmm1
Видно что он сразу пишет значения в структуру указатель на которую лежит в rcx, а вызывающая функция заботливо положила туда указатель на локальную переменную.
Структура более не возвращается в регистре.
С инлайнигом:
000007FF001837C4 xor eax,eax
000007FF001837C6 mov qword ptr [rsp+20h],rax
Т.к. Vector2 небольшая структура (два флоата - 8 байт), то вся структура помещается в rax. Видно что код не отличается от 1 примера вообще никак.
__________________
|
(Offline)
|
|
Эти 5 пользователя(ей) сказали Спасибо h1dd3n за это полезное сообщение:
|
|
22.08.2016, 21:07
|
#11
|
Бывалый
Регистрация: 19.06.2008
Сообщений: 679
Написано 264 полезных сообщений (для 450 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Сообщение от Жека
А вот кастинг типа при каждой установке свойства в классе Transform
Почему бы в сеттер не воткнуть SetParent.
|
Я не разбираюсь в юнити и не могу знать чем SetParent лучше, но если тебя волнует что там проверка типа через оператор is в сеттере, то это врятли проблема ибо Debug.LogWarning при релизном билде должно быть выкинуто нахер компилятором, а значит там остается только условие if без тела, которое, разумеется, тоже будет выкинуто нахер компилятором. То есть там этого кода как будто вообще не было.
__________________
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо h1dd3n за это полезное сообщение:
|
|
22.08.2016, 21:16
|
#12
|
Элита
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,158
Написано 502 полезных сообщений (для 1,012 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
Сообщение от h1dd3n
Добавлю
var vector = new Vector2(0, 0);
000007FF001735A4 xor eax,eax
000007FF001735A6 mov qword ptr [rsp+20h],rax
Без инлайнинга ([MethodImpl(MethodImplOptions.NoInlining)]):
var vector = Vector2.Zero;
000007FF0019348E call 000007FF0005C940
000007FF00193493 mov qword ptr [rsp+28h],rax
Здесь в rax - вся структура (8 байт). Код был бы немного другим если бы структура не влезала в регистр целиком:
Это код геттера для Vector3
000007FE7F9D4670 vxorps xmm0,xmm0,xmm0
000007FE7F9D4675 vxorps xmm1,xmm1,xmm1
000007FE7F9D467A vmovss dword ptr [rcx],xmm0
000007FE7F9D467F vmovss dword ptr [rcx+4],xmm1
000007FE7F9D4685 vmovss dword ptr [rcx+8],xmm1
Видно что он сразу пишет значения в структуру указатель на которую лежит в rcx, а вызывающая функция заботливо положила туда указатель на локальную переменную.
Структура более не возвращается в регистре.
С инлайнигом:
000007FF001837C4 xor eax,eax
000007FF001837C6 mov qword ptr [rsp+20h],rax
Т.к. Vector2 небольшая структура (два флоата - 8 байт), то вся структура помещается в rax. Видно что код не отличается от 1 примера вообще никак.
|
Раскидал, что не подкопаться
|
(Offline)
|
|
23.08.2016, 06:24
|
#13
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
h1dd3n, большое спасибо за объяснения!
|
(Offline)
|
|
25.08.2016, 11:25
|
#14
|
Бывалый
Регистрация: 26.07.2009
Сообщений: 785
Написано 362 полезных сообщений (для 995 пользователей)
|
Ответ: Decompiled Unity5.3 (c#)
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 03:06.
|