forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Unity (http://forum.boolean.name/forumdisplay.php?f=144)
-   -   Decompiled Unity5.3 (c#) (http://forum.boolean.name/showthread.php?t=20381)

Жека 20.08.2016 07:36

Decompiled Unity5.3 (c#)
 
Декомпиленные исходники шарповской части юнити5.3
ссылка на гитхаб

Как и ожидалось, почти весь код - это врапперы над c++ ядром.

Жека 20.08.2016 07:54

Ответ: Decompiled Unity5.3 (c#)
 
Зацените функцию:
PHP код:

[TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
public static 
Object FindObjectOfType(Type type)
{
    
Object[] objArray FindObjectsOfType(type);
    if (
objArray.Length 0)
    {
        return 
objArray[0];
    }
    return 
null;


выгребаются все объекты и берётся первый. как-то расточительно.

Жека 20.08.2016 17:22

Ответ: Decompiled Unity5.3 (c#)
 
А вот кастинг типа при каждой установке свойства в классе Transform
PHP код:

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.

ABTOMAT 20.08.2016 20:07

Ответ: Decompiled Unity5.3 (c#)
 
Цитата:

Сообщение от Жека (Сообщение 307931)
Зацените функцию:
PHP код:

[TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
public static 
Object FindObjectOfType(Type type)
{
    
Object[] objArray FindObjectsOfType(type);
    if (
objArray.Length 0)
    {
        return 
objArray[0];
    }
    return 
null;


выгребаются все объекты и берётся первый. как-то расточительно.

Спасибо! Теперь буду знать, что это не дешевле чем взять всё.

Жека 21.08.2016 11:38

Ответ: Decompiled Unity5.3 (c#)
 
Все предустановленные направления вектора реализованы так:
PHP код:

public static Vector2 zero
        
{
            
get
            
{
                return new 
Vector2(0f0f);
            }
        }
        public static 
Vector2 one
        
{
            
get
            
{
                return new 
Vector2(1f1f);
            }
        } 

Каждый раз создаётся новый вектор. Наверное для стэковой памяти это не затратно.
Хотя я читал, что при присвоении типа struct в переменную создается копия. Получается, тут будет дважды создана копия:
PHP код:

var Vector2.one

Или нет?

Жека 21.08.2016 11:47

Ответ: Decompiled Unity5.3 (c#)
 
Ещё стал интесесен вопрос юзания оператора foreach. На каждый форыч создаётся новый объект-итератор.
Если не предполагается пробегать по той же коллекции внутри другого форыча, то можно бы сделать кэшированный итератор, для которого вместо new будет вызываться iterator.reset (this) - сбрасываем индекс в ноль или ссылку на first.

В манки-юнити хочу сделать такой кэш-вариант для списков, которые не торчат наружу в юзерский код.

Жека 21.08.2016 12:08

Ответ: Decompiled Unity5.3 (c#)
 
Цитата:

Теперь буду знать, что это не дешевле чем взять всё.
А где эта функция нужна?
Я не встречал, вроде - ни в проектах, ни в других файлах исходников.

h1dd3n 22.08.2016 20:06

Ответ: Decompiled Unity5.3 (c#)
 
Цитата:

Сообщение от Жека (Сообщение 307962)
Все предустановленные направления вектора реализованы так:
PHP код:

public static Vector2 zero
        
{
            
get
            
{
                return new 
Vector2(0f0f);
            }
        }
        public static 
Vector2 one
        
{
            
get
            
{
                return new 
Vector2(1f1f);
            }
        } 

Каждый раз создаётся новый вектор. Наверное для стэковой памяти это не затратно.
Хотя я читал, что при присвоении типа struct в переменную создается копия. Получается, тут будет дважды создана копия:
PHP код:

var Vector2.one

Или нет?

Нет, не будет.
Все правильно читал - значимые типы в дотнете "копируются" при присвоении. Однако в приведенном тобой примере есть только 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;
это одно и тоже.

h1dd3n 22.08.2016 20:19

Ответ: Decompiled Unity5.3 (c#)
 
Цитата:

Сообщение от Жека (Сообщение 307964)
Ещё стал интесесен вопрос юзания оператора foreach. На каждый форыч создаётся новый объект-итератор.
Если не предполагается пробегать по той же коллекции внутри другого форыча, то можно бы сделать кэшированный итератор, для которого вместо new будет вызываться iterator.reset (this) - сбрасываем индекс в ноль или ссылку на first.

В манки-юнити хочу сделать такой кэш-вариант для списков, которые не торчат наружу в юзерский код.

Да, итератор создается каждый раз. Но это совершенно ничего не значит. Создание объекта ничего не стоит. Да, серьезно, ничего не стоит. Аллокация памяти в дотнете нереально быстрая (как и в яве, например), ибо память то уже аллоцирована одним большим куском. Вот когда сборщик мусора начинает работать, то огромное кол-во объектов может стать для него проблемой. Но речь идет о десятках гигабайт и миллиардах объектов в секунду. К тому же аллокация и сборщик работают только на ссылочных типах, значимые то хранятся на стеке. Память то там не аллоцируется, и сборщик потом такие объекты не собирает. И итератор такой распостраненной коллекции как List<T>, например, объявлен как struct, а значит вся эта фигня с кешированием ничего не даст.
http://referencesource.microsoft.com...661cf752ff3f44

h1dd3n 22.08.2016 21:04

Ответ: 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 примера вообще никак.

h1dd3n 22.08.2016 21:07

Ответ: Decompiled Unity5.3 (c#)
 
Цитата:

Сообщение от Жека (Сообщение 307941)
А вот кастинг типа при каждой установке свойства в классе Transform
Почему бы в сеттер не воткнуть SetParent.

Я не разбираюсь в юнити и не могу знать чем SetParent лучше, но если тебя волнует что там проверка типа через оператор is в сеттере, то это врятли проблема ибо Debug.LogWarning при релизном билде должно быть выкинуто нахер компилятором, а значит там остается только условие if без тела, которое, разумеется, тоже будет выкинуто нахер компилятором. То есть там этого кода как будто вообще не было.

RegIon 22.08.2016 21:16

Ответ: Decompiled Unity5.3 (c#)
 
Цитата:

Сообщение от h1dd3n (Сообщение 308002)
Добавлю
Код:

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 примера вообще никак.

Раскидал, что не подкопаться:super:

Жека 23.08.2016 06:24

Ответ: Decompiled Unity5.3 (c#)
 
h1dd3n, большое спасибо за объяснения!

Andvrok 25.08.2016 11:25

Ответ: Decompiled Unity5.3 (c#)
 
https://habrahabr.ru/company/pvs-studio/blog/308336/


Часовой пояс GMT +4, время: 15:50.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot