Вопрос по распаковке (unboxing)
От: Аноним  
Дата: 21.02.11 12:41
Оценка:
Все мы знаем, что при распаковке упакованного объекта value-типа происходит простое определение адреса значения без копирования данных, в отличие от операции упаковки, в которой происходит выделение памяти и копирование данных. Теперь вопрос, как правильно ответить на вот этот вопрос теста:


Complete the following sentence: When unboxing occurs_______


  1. The contents of a value type are copied from the stack into the memory allocated on the managed heap
  2. Memory is copied from the managed heap to the stack
  3. All the local variables within a function are unboxed from a class
  4. All the variables within a function are unboxed from a class

Моя логика говорит, что скорее всего разработчик думал о 2-м варианте, но суть то его неверная. 3-й и 4-й вариант мне, честно говоря непонятны вообще, возможно ответ скрыт там?
Re: Вопрос по распаковке (unboxing)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.11 12:55
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Все мы знаем, что при распаковке упакованного объекта value-типа происходит простое определение адреса значения без копирования данных, в отличие от операции упаковки, в которой происходит выделение памяти и копирование данных.

Полагаю, что далеко не все об этом знают. Сам узнал на неделе об этом, хотя с дотнетом знаком с 2003-го года.
Но еще не успел выяснить, происходит ли копирование при
int i = (int)o; // where System.Object o;
Как варианты — оно может происходить но уже вне процесса анбоксинга, либо действительно не происходит.

A>Теперь вопрос, как правильно ответить на вот этот вопрос теста:

Обладая знанием этой тонкости, никак

А>Complete the following sentence: When unboxing occurs_______


А>

    А>
  1. The contents of a value type are copied from the stack into the memory allocated on the managed heap
    А>
  2. Memory is copied from the managed heap to the stack
    А>
  3. All the local variables within a function are unboxed from a class
    А>
  4. All the variables within a function are unboxed from a class
    А>

А>Моя логика говорит, что скорее всего разработчик думал о 2-м варианте, но суть то его неверная. 3-й и 4-й вариант мне, честно говоря непонятны вообще, возможно ответ скрыт там?


Действительно, автор подразумевал вариант 2. В 3 и 4 написан шум для любителей угадывать.
Re: Вопрос по распаковке (unboxing)
От: mrjeka Россия  
Дата: 21.02.11 13:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Все мы знаем, что при распаковке упакованного объекта value-типа происходит простое определение адреса значения без копирования данных, в отличие от операции упаковки, в которой происходит выделение памяти и копирование данных. Теперь вопрос, как правильно ответить на вот этот вопрос теста:



А>Complete the following sentence: When unboxing occurs_______



А>

    А>
  1. The contents of a value type are copied from the stack into the memory allocated on the managed heap
    А>
  2. Memory is copied from the managed heap to the stack
    А>
  3. All the local variables within a function are unboxed from a class
    А>
  4. All the variables within a function are unboxed from a class
    А>

А>Моя логика говорит, что скорее всего разработчик думал о 2-м варианте, но суть то его неверная. 3-й и 4-й вариант мне, честно говоря непонятны вообще, возможно ответ скрыт там?


А не уверен что без копирования.
допустим код:
object o = 3;
int x = (int)o;//распаковка
int y = (int)o;//распаковка
x = x + 1;
Console.WriteLine(y);//Выведет 3


Если бы происходило просто определение адреса без копирования данных, то при изменении "х" должно было бы измениться значение "у". Или я все не так понимаю?
Re[2]: Вопрос по распаковке (unboxing)
От: 1stein Украина  
Дата: 21.02.11 13:13
Оценка:
Здравствуйте, mrjeka, Вы писали:

M>А не уверен что без копирования.

M>допустим код:
M>
M>object o = 3;
M>int x = (int)o;//распаковка
M>int y = (int)o;//распаковка
M>x = x + 1;
M>Console.WriteLine(y);//Выведет 3
M>


M>Если бы происходило просто определение адреса без копирования данных, то при изменении "х" должно было бы измениться значение "у". Или я все не так понимаю?


эквивалентно:
int x = 3;
int y = 3;
x = x + 1;
Console.WriteLine(y);//Выведет 3
Will code C# for food
Re[2]: Вопрос по распаковке (unboxing)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.11 13:15
Оценка:
Здравствуйте, mrjeka, Вы писали:

M>А не уверен что без копирования.

M>допустим код:
M>
M>object o = 3;
M>int x = (int)o;//распаковка
M>int y = (int)o;//распаковка
M>x = x + 1;
M>Console.WriteLine(y);//Выведет 3
M>


M>Если бы происходило просто определение адреса без копирования данных, то при изменении "х" должно было бы измениться значение "у". Или я все не так понимаю?


Возможно что при попытке изменения копирование происходит, иначе нет.
Re[2]: Вопрос по распаковке (unboxing)
От: Аноним  
Дата: 21.02.11 13:22
Оценка: 8 (1) +1
Здравствуйте, samius, Вы писали:

S>Но еще не успел выяснить, происходит ли копирование при

S>int i = (int)o; // where System.Object o;
S>Как варианты — оно может происходить но уже вне процесса анбоксинга, либо действительно не происходит.
(int)o; Не приведет к копированию. А вот int i= (int)o; — приведет, так как как раз операция присвоения и есть операцией копирования. Т.е. она вне процесса анбоксинга.
Re[3]: Вопрос по распаковке (unboxing)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.11 13:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, samius, Вы писали:


S>>Но еще не успел выяснить, происходит ли копирование при

S>>int i = (int)o; // where System.Object o;
S>>Как варианты — оно может происходить но уже вне процесса анбоксинга, либо действительно не происходит.
А>(int)o; Не приведет к копированию. А вот int i= (int)o; — приведет, так как как раз операция присвоения и есть операцией копирования. Т.е. она вне процесса анбоксинга.
Да, выглядит логично.
Re[2]: Вопрос по распаковке (unboxing)
От: _FRED_ Черногория
Дата: 21.02.11 13:29
Оценка:
Здравствуйте, samius, Вы писали:

S>Но еще не успел выяснить, происходит ли копирование при

S>int i = (int)o; // where System.Object o;

Локальные переменные хранятся на стеке, а размер стека и распределение переменных в нём рассчитывает компилятор. Маловероятно, что бы при этом рассчёте компилятору удалось бы вычислить, что для переменной "i" не нужно резервировать место
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Вопрос по распаковке (unboxing)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.11 13:46
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, samius, Вы писали:


S>>Но еще не успел выяснить, происходит ли копирование при

S>>int i = (int)o; // where System.Object o;

_FR>Локальные переменные хранятся на стеке, а размер стека и распределение переменных в нём рассчитывает компилятор. Маловероятно, что бы при этом рассчёте компилятору удалось бы вычислить, что для переменной "i" не нужно резервировать место

Но не исключено.
Вообще Аноним прояснил этот момент, что копирование происходит все же, но уже вне боксинга. И здесь ((Foo)o).Bar() копирования не будет.
Re: Вопрос по распаковке (unboxing)
От: Lloyd Россия  
Дата: 21.02.11 14:00
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Все мы знаем, что при распаковке упакованного объекта value-типа происходит простое определение адреса значения без копирования данных, в отличие от операции упаковки, в которой происходит выделение памяти и копирование данных.


Не могли бы вы подробнее прокомментировать это? Опрделили мы адрес в кучи, что дальше с ним делать-то без копирования данных? Каким образом код, обращающийся к переменной, лежащей на стеке, получит верное значение?
Re[2]: Вопрос по распаковке (unboxing)
От: Sinix  
Дата: 21.02.11 14:43
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Не могли бы вы подробнее прокомментировать это? Опрделили мы адрес в кучи, что дальше с ним делать-то без копирования данных? Каким образом код, обращающийся к переменной, лежащей на стеке, получит верное значение?

У Рихтера подробно рассматривалось. Книжки под рукой нет.
Re[3]: Вопрос по распаковке (unboxing)
От: mrjeka Россия  
Дата: 22.02.11 05:07
Оценка:
Здравствуйте, 1stein, Вы писали:

1>Здравствуйте, mrjeka, Вы писали:


M>>А не уверен что без копирования.

M>>допустим код:
M>>
M>>object o = 3;
M>>int x = (int)o;//распаковка
M>>int y = (int)o;//распаковка
M>>x = x + 1;
M>>Console.WriteLine(y);//Выведет 3
M>>


M>>Если бы происходило просто определение адреса без копирования данных, то при изменении "х" должно было бы измениться значение "у". Или я все не так понимаю?


1>эквивалентно:

1>
1>int x = 3;
1>int y = 3;
1>x = x + 1;
1>Console.WriteLine(y);//Выведет 3
1>


Не эквивалентно. В вашем случае вы сразу создаете переменные в стеке.
Re[2]: Вопрос по распаковке (unboxing)
От: MozgC США http://nightcoder.livejournal.com
Дата: 22.02.11 05:14
Оценка: 18 (1)
Здравствуйте, Lloyd, Вы писали:

L>Не могли бы вы подробнее прокомментировать это? Опрделили мы адрес в кучи, что дальше с ним делать-то без копирования данных? Каким образом код, обращающийся к переменной, лежащей на стеке, получит верное значение?


Now that you know how boxing works, let’s talk about unboxing. Let’s say that you want to grab the first element out of the ArrayList by using the following code:

Point p = (Point) a[0];

Here you’re taking the reference (or pointer) contained in element 0 of the ArrayList and trying to put it into a Point value type instance, p. For this to work, all of the fields contained in the boxed Point object must be copied into the value type variable, p, which is on the thread’s stack. The CLR accomplishes this copying in two steps. First, the address of the Point fields in the boxed Point object is obtained. This process is called unboxing. Then, the values of these fields are copied from the heap to the stack-based value type instance.

Unboxing is not the exact opposite of boxing. The unboxing operation is much less costly than boxing. Unboxing is really just the operation of obtaining a pointer to the raw value type (data fields) contained within an object. In effect, the pointer refers to the unboxed portion in the boxed instance. So, unlike boxing, unboxing doesn’t involve the copying of any bytes in memory. Having made this important clarification, it is important to note that an unboxing operation is typically followed by copying the fields.

(c) Richter, CLR via C#, 3rd edition.
Re[3]: Вопрос по распаковке (unboxing)
От: Lloyd Россия  
Дата: 22.02.11 06:21
Оценка: 1 (1) +1
Здравствуйте, MozgC, Вы писали:

L>>Не могли бы вы подробнее прокомментировать это? Опрделили мы адрес в кучи, что дальше с ним делать-то без копирования данных? Каким образом код, обращающийся к переменной, лежащей на стеке, получит верное значение?


MC>

Now that you know how boxing works, let’s talk about unboxing. Let’s say that you want to grab the first element out of the ArrayList by using the following code:

MC>

Point p = (Point) a[0];

MC>Here you’re taking the reference (or pointer) contained in element 0 of the ArrayList and trying to put it into a Point value type instance, p. For this to work, all of the fields contained in the boxed Point object must be copied into the value type variable, p, which is on the thread’s stack. The CLR accomplishes this copying in two steps. First, the address of the Point fields in the boxed Point object is obtained. This process is called unboxing. Then, the values of these fields are copied from the heap to the stack-based value type instance.

MC>Unboxing is not the exact opposite of boxing. The unboxing operation is much less costly than boxing. Unboxing is really just the operation of obtaining a pointer to the raw value type (data fields) contained within an object. In effect, the pointer refers to the unboxed portion in the boxed instance. So, unlike boxing, unboxing doesn’t involve the copying of any bytes in memory. Having made this important clarification, it is important to note that an unboxing operation is typically followed by copying the fields.

MC>(c) Richter, CLR via C#, 3rd edition.

Это уже терминологическая подтасовка. Поскольку все равно после такого unboxing-а следует "the values of these fields are copied from the heap to the stack-based value type instance.", то разделять две этих операции нет никакого смысла.

Если перевести на повседневный язык:

Подтянться 50 раз — легче легкого. Это делается за 2 шага. Сначала просто подходишь к перекладине, протягиваешь руки и хватаешься за нее. Это называется "подтягивание". Потом 50 раз тянешь свою тушку вверх.

Re[4]: Вопрос по распаковке (unboxing)
От: MozgC США http://nightcoder.livejournal.com
Дата: 22.02.11 06:40
Оценка: 43 (4)
Здравствуйте, Lloyd, Вы писали:

MC>>
Point p = (Point) a[0];

L>Это уже терминологическая подтасовка. Поскольку все равно после такого unboxing-а следует "the values of these fields are copied from the heap to the stack-based value type instance.", то разделять две этих операции нет никакого смысла.

var x = ((Point) a[0]).X;

Вот тут не будет копирования. Значит нет unboxing'а?
Re[5]: Вопрос по распаковке (unboxing)
От: Lloyd Россия  
Дата: 22.02.11 07:57
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>
var x = ((Point) a[0]).X;

MC>Вот тут не будет копирования. Значит нет unboxing'а?

Нет, значит есть оптимизация.
Re[5]: Вопрос по распаковке (unboxing)
От: 1stein Украина  
Дата: 22.02.11 09:53
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, Lloyd, Вы писали:


MC>>>
Point p = (Point) a[0];

L>>Это уже терминологическая подтасовка. Поскольку все равно после такого unboxing-а следует "the values of these fields are copied from the heap to the stack-based value type instance.", то разделять две этих операции нет никакого смысла.

MC>
var x = ((Point) a[0]).X;

MC>Вот тут не будет копирования. Значит нет unboxing'а?

object p = new Point(1, 1);
int x = ((Point)p).X;



.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 3
    .locals init (
        [0] object p,
        [1] int32 x,
        [2] valuetype [System.Drawing]System.Drawing.Point CS$0$0000)
    L_0000: nop 
    L_0001: ldc.i4.1 
    L_0002: ldc.i4.1 
    L_0003: newobj instance void [System.Drawing]System.Drawing.Point::.ctor(int32, int32)
    L_0008: box [System.Drawing]System.Drawing.Point
    L_000d: stloc.0 
    L_000e: ldloc.0 
    L_000f: unbox.any [System.Drawing]System.Drawing.Point
    L_0014: stloc.2 
    L_0015: ldloca.s CS$0$0000
    L_0017: call instance int32 [System.Drawing]System.Drawing.Point::get_X()
    L_001c: stloc.1 
    L_001d: ret 
}


Здается мне господа, это все-таки копирование (L_0014)
Will code C# for food
Re[6]: Вопрос по распаковке (unboxing)
От: drol  
Дата: 22.02.11 10:30
Оценка: 1 (1)
Здравствуйте, 1stein, Вы писали:

1>Здается мне господа, это все-таки копирование (L_0014)


В этом примере генерится unbox.any — это да, копирование. Однако в IL есть и инструкция unbox — она возвращает указатель.
Re[6]: Вопрос по распаковке (unboxing)
От: Аноним  
Дата: 22.02.11 12:51
Оценка:
Здравствуйте, 1stein, Вы писали:

1>Здается мне господа, это все-таки копирование (L_0014)


Тогда так:
#include "stdafx.h"

using namespace System;

value struct Point
{
    int X,Y;
    Point(int x, int y):X(x),Y(y){}
};

int main(array<System::String ^> ^args)
{
    Point a(1,2);
    Object ^ o = a;

    dynamic_cast<Point^>(o)->X=42;
}


Компилируется в:
.method assembly static int32 main(string[] args) cil managed
{
    .maxstack 3
    .locals (
        [0] object o,
        [1] valuetype Point a)
    L_0000: ldnull 
    L_0001: stloc.0 
    L_0002: ldloca.s a
    L_0004: ldc.i4.1 
    L_0005: ldc.i4.2 
    L_0006: call instance void Point::.ctor(int32, int32)
    L_000b: ldloc.1 
    L_000c: box Point
    L_0011: stloc.0 
    L_0012: ldloc.0 
    L_0013: isinst Point
    L_0018: unbox Point
    L_001d: ldc.i4.s 0x2a
    L_001f: stfld int32 Point::X
    L_0024: ldc.i4.0 
    L_0025: ret 
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.