Net framework 5, а также среды Visual Studio 2012 и C#



Download 6,27 Mb.
Pdf ko'rish
bet115/658
Sana12.06.2023
Hajmi6,27 Mb.
#950840
1   ...   111   112   113   114   115   116   117   118   ...   658
Bog'liq
CLR via C Programmirovanie na platforme Microsoft NET Framework 4 5 na yazyke C


Глава.5 .Примитивные,.ссылочные.и.значимые.типы
формируется путем конкатенации трех элементов, компилятор выбирает следую-
щую версию метода 
Concat
:
public static String Concat(Object arg0, Object arg1, Object arg2); 
В качестве первого параметра, 
arg0
, передается 
v
. Но 
v
— это неупакованное 
значение, а 
arg0
— это значение 
Object
, поэтому экземпляр 
v
нужно упаковать, 
а его адрес передать в качестве 
arg0
. Параметром 
arg1
является строка 
","
в виде 
ссылки на объект 
String
. И наконец, чтобы передать параметр 
arg2

o
(ссылка на 
Object
) приводится к типу 
Int32
. Для этого нужна распаковка (но без копирова-
ния), при которой извлекается адрес неупакованного экземпляра 
Int32
внутри 
упакованного экземпляра 
Int32
. Этот неупакованный экземпляр 
Int32
надо опять 
упаковать, а его адрес в памяти передать в качестве параметра 
arg2
методу 
Concat
.
Метод 
Concat
вызывает методы 
ToString
для каждого указанного объекта и вы-
полняет конкатенацию строковых представлений этих объектов. Возвращаемый 
из 
Concat
объект 
String
передается затем методу 
WriteLine
, который отображает 
окончательный результат.
Полученный IL-код станет эффективнее, если обращение к 
WriteLine
пере-
писать:
Console.WriteLine(v + ", " + o); // Отображается "123, 5" 
Этот вариант строки отличается от предыдущего только отсутствием для пере-
менной 
o
операции приведения типа 
(Int32)
. Этот код выполняется быстрее, так 
как 
o
уже является ссылочным типом 
Object
и его адрес можно сразу передать 
методу 
Concat
. Отказавшись от приведения типа, я избавился от двух операций: 
распаковки и упаковки. В этом легко убедиться, если заново собрать приложение 
и посмотреть на сгенерированный IL-код:
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Размер кода 35 (0x23)
.maxstack 3
.locals init ([0] int32 v,
[1] object o)
// Загружаем 5 в v
IL_0000: ldc.i4.5
IL_0001: stloc.0 
// Упакуем v и сохраняем указатель в o
IL_0002: ldloc.0
IL_0003: box [mscorlib]System.Int32
IL_0008: stloc.1
// Загружаем 123 в v
IL_0009: ldc.i4.s 123
IL_000b: stloc.0


163
Упаковка.и.распаковка.значимых.типов
// Упакуем v и сохраняем в стеке указатель для Concat
IL_000c: ldloc.0
IL_000d: box [mscorlib]System.Int32
// Загружаем строку в стек для Concat
IL_0012: ldstr ", "
// Загружаем в стек адрес упакованного Int32 для Concat
IL_0017: ldloc.1
// Вызываем Concat
IL_0018: call string [mscorlib]System.String::Concat(object,
object,
object)
// Строку, возвращенную из Concat, передаем в WriteLine
IL_001d: call void [mscorlib]System.Console::WriteLine(string)
// Main возвращает управление, чем завершается работа приложения
IL_0022: ret
} // Конец метода App::Main
Беглое сравнение двух версий IL-кода метода 
Main
показывает, что вариант без 
приведения типа 
Int32
на 10 байт меньше, чем вариант с приведением типа. До-
полнительные операции распаковки/упаковки, безусловно, приводят к разрастанию 
кода. Если мы пойдем дальше, то увидим, что эти операции потребуют выделения 
памяти в управляемой куче для дополнительного объекта, которую в будущем дол-
жен освободить уборщик мусора. Конечно, обе версии приводят к одному результату 
и разница в скорости незаметна, однако лишние операции упаковки, выполняемые 
многократно (например, в цикле), могут заметно повлиять на производительность 
приложения и расходование памяти.
Предыдущий код можно улучшить, изменив вызов метода 
WriteLine
:
Console.WriteLine(v.ToString() + ", " + o); // Отображается "123, 5"
Для неупакованного значимого типа 
v
теперь вызывается метод 
ToString
, воз-
вращающий 
String
. Строковые объекты являются ссылочными типами и могут 
легко передаваться в метод 
Concat
без упаковки.
Вот еще один пример, демонстрирующий упаковку и распаковку:
public static void Main() { 
Int32 v = 5; // Создаем неупакованную переменную значимого типа
Object o = v; // o указывает на упакованную версию v
v = 123; // Изменяет неупакованный значимый тип на 123
Console.WriteLine(v); // Отображает "123"
v = (Int32) o; // Распаковывает и копирует o в v
Console.WriteLine(v); // Отображает "5"



164
Download 6,27 Mb.

Do'stlaringiz bilan baham:
1   ...   111   112   113   114   115   116   117   118   ...   658




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish