Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Array.Length (да и в String) - как устроено? 
V
    Опции темы
Arks
  Дата 12.12.2006, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Интересует, что делают эти свойства: считывают значения из какой-то переменной или вычисляют? Как это в массиве и строках организовано?
Просто интересует надо ли запихивать в цикле эти данные отдельную переменную или также эффективно будет напрямую свойства читать?
PM MAIL ICQ Skype MSN   Вверх
ivashkanet
Дата 12.12.2006, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Arks, конечно считывают. 
Уж сильно часто эта длинна используется.

Для таких вопросов есть reflector

Это сообщение отредактировал(а) ivashkanet - 12.12.2006, 10:14
PM MAIL WWW ICQ   Вверх
mr.DUDA
Дата 12.12.2006, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



В рефлекторе такие свойства помечены атрибутом [MethodImpl(MethodImplOptions.InternalCall)] и не имеют реализации  smile 


--------------------
user posted image
PM MAIL WWW   Вверх
ivashkanet
Дата 12.12.2006, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(mr.DUDA @  12.12.2006,  11:47 Найти цитируемый пост)
[MethodImpl(MethodImplOptions.InternalCall)]

 smile 
А во всяких ArrayList, List<T> --- длина храниться smile 
 smile Наверное потому, что не может быть вычислена  smile 
PM MAIL WWW ICQ   Вверх
Arks
Дата 12.12.2006, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Спасибо за ответы.
Для ivashkanet, неа. Потому что, вычислять долго и неэффективно, как и для массива. Или что ты имел в виду?

Это сообщение отредактировал(а) Arks - 12.12.2006, 16:36
PM MAIL ICQ Skype MSN   Вверх
ivashkanet
Дата 12.12.2006, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(mr.DUDA @  12.12.2006,  11:47 Найти цитируемый пост)
[MethodImpl(MethodImplOptions.InternalCall)]

Это как раз и означает, что длина обычного массива вычисляется. Но не обычными средствами, а низкоуровневыми. 
Типа <размер в байтах> /4 . А может и еще круче  smile 
PM MAIL WWW ICQ   Вверх
Arks
Дата 12.12.2006, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Так вы уж определитесь пожалуйста с когда вычисляется, когда нет? smile

Добавлено @ 17:12 
Кстати, я в рефлекторе ничего путного не нашёл:
Код
public: System::Int32 __gc* GetLength(System::Int32 __gc* dimension)
{
      return System::PInvoke::EE::Array_GetLength(this, dimension);
}

Мне это ровным счётом ничего не говорит.
PM MAIL ICQ Skype MSN   Вверх
ivashkanet
Дата 12.12.2006, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(Arks @  12.12.2006,  16:04 Найти цитируемый пост)
Так вы уж определитесь пожалуйста с когда вычисляется, когда нет? 

Во первых: а наф оно тебе?
Во вторых: Дуда же написал, что у этого свойства стоит атрибут MethodImpl(MethodImplOptions.InternalCall). 
Если перевести на русский, то РеализацияМетода(ВнутреннийВызов).

Что еще не понятно?
PM MAIL WWW ICQ   Вверх
Arks
Дата 12.12.2006, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



1) Хочу знать как эффективнее - не охото, чтобы он в цикле тьму времени терял на вызовы фунцкий.
2) Из того, что сказал Дуда, я так понял, что длина в свойствах с MethodImpl(MethodImplOptions.InternalCall) хранится, а через пост ты сказал, что вычисляется. Так где правда?
И в том коде, что я показал как раз и есть этот внутренний вызов? MethodImpl(MethodImplOptions.InternalCall)?
Так?
PM MAIL ICQ Skype MSN   Вверх
ivashkanet
Дата 12.12.2006, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(Arks @  12.12.2006,  18:00 Найти цитируемый пост)
Хочу знать как эффективнее 

Зависит от ситуации.
Например для обычных массивов она вычисляется, а для коллекций --- хранится.
Цитата(Arks @  12.12.2006,  18:00 Найти цитируемый пост)
Так где правда?

См. выше и перечитай тему сначала.
Цитата(Arks @  12.12.2006,  18:00 Найти цитируемый пост)
И в том коде, что я показал как раз и есть этот внутренний вызов?

Нет. Там только вызов метода Array_GetLength. Нажми на него и посмотри что именно вызывается.

PM MAIL WWW ICQ   Вверх
mr.DUDA
Дата 12.12.2006, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Для строк размер стопудово хранится, а не вычисляется, т.к. строка - неизменяемый объект. Не хранится прямо в классе String по гейтс знает каким причинам, возможно это как-то связано с возможностью интернирования строк. Размер Array также неизменяемая величина, но здесь сложнее сказать, почему размер не хранится в классе. И тот и другой класс имеют синтаксические аналоги - возможно, причина как-то связана и с этим. В любом случае, нам остаётся только гадать. Хотя может в гугле что-то найдётся по этому поводу...


--------------------
user posted image
PM MAIL WWW   Вверх
ivashkanet
Дата 12.12.2006, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(mr.DUDA @  12.12.2006,  18:22 Найти цитируемый пост)
Для строк размер стопудово хранится

С чего это ты взял? Для строк стоит тот же MethodImpl(MethodImplOptions.InternalCall).
Цитата(mr.DUDA @  12.12.2006,  18:22 Найти цитируемый пост)
по гейтс знает каким причинам

А вот это чистая правда  smile 
PM MAIL WWW ICQ   Вверх
mr.DUDA
Дата 12.12.2006, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(ivashkanet @  12.12.2006,  18:27 Найти цитируемый пост)
С чего это ты взял? Для строк стоит тот же MethodImpl(MethodImplOptions.InternalCall).

С того, что
Цитата(mr.DUDA @  12.12.2006,  18:22 Найти цитируемый пост)
 т.к. строка - неизменяемый объект.




--------------------
user posted image
PM MAIL WWW   Вверх
ivashkanet
Дата 13.12.2006, 08:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Нее, mr.DUDA, так и массив такой же неизменяемый  smile 

Хочу оговориться: Я бы хранил это значение, но меня смущает InternalCall  smile 

А вообще --- какая хрен разница  smile 
PM MAIL WWW ICQ   Вверх
Arks
Дата 13.12.2006, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



А вот на что ссылается тот код:
Код
[System::Runtime::InteropServices::DllImport(S"mscoree", EntryPoint=S"#14")]
public: static extern System::Int32 __gc* Array_GetLength(System::Object __gc* array, System::Int32 __gc* dimension);

Что он делает я честно говоря не врубился, зато нашёл кое-что другое.

Длина строки действительно хранится. Вот:
Код
public private: System::Int32 __gc* StringLength;

Длина массива похоже хранится в этой переменной:
Код
private: System::Int32 __gc* cElems;


Это сообщение отредактировал(а) Arks - 13.12.2006, 09:53
PM MAIL ICQ Skype MSN   Вверх
Void
Дата 15.12.2006, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 25
Всего: 173



Массивы так глубоко зашиты в рантайм, что такие вещи надо скорее не рефлектором смотреть, а в Роторе.

Или смотреть сгенерированный машинный код с помощью cordbg, только не забыть m JitOptimizations 1.

На простеньком коде:
Код
using System;

class Test
{
    static void Main()
    {
        int[] a = new int[10];
        int s = 0;
        for (int i = 0; i < a.Length; ++i)
            a[i] = i;
        for (int i = 0; i < a.Length; ++i)
            s += a[i];
    }
}

выяснилось, что длина массива хранится со смещением 4 байта от адреса объекта в памяти, дальше следует непосредственно содержимое массива.
JIT загнал адрес a в регистр, но поместить длину в регистр не догадался. Равно как и не догадался убрать проверку на выход за границу массива.

Длина строки хранится со смещением +8 байт.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Yama
Дата 15.12.2006, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 2.8.2006

Репутация: 2
Всего: 2



Цитата(mr.DUDA @  12.12.2006,  18:22 Найти цитируемый пост)
Для строк размер стопудово хранится, а не вычисляется, т.к. строка - неизменяемый объект. Не хранится прямо в классе String по гейтс знает каким причинам, возможно это как-то связано с возможностью интернирования строк. Размер Array также неизменяемая величина, но здесь сложнее сказать, почему размер не хранится в классе. И тот и другой класс имеют синтаксические аналоги - возможно, причина как-то связана и с этим. В любом случае, нам остаётся только гадать. Хотя может в гугле что-то найдётся по этому поводу...

В любом случае на низком уровне сам текст строки хранится в виде массива *char. Я когда-то баловался тем, что писал на C++ класс типа MyString, в котором реализовывал и свойства Length (правда, как функцию, которая возврашает длину строки smile  ), и ToAnything(),  и тому подобное. Тогда же смотрел исходники класса String, который встроен в Borland C++ Builder - как оказалось, там была практически такая же реализация класса стринг, как и у меня, ток чуток понавороченней. Сам класс String - это лишь, по сути,  *char, к которому внутри класса добавили функций, свойств и методов, что бы удебней работать было  smile .
Сама по себе строка, если изначально не определена как const - величина изменяемая и измеряемая, причем метод измерения длины оной строки может варьироваться в зависимости от реализации методов - от запроса функции mystr.Length(), которая вычисляет длину в момент запроса, выдет ее и прекращает свое существование, до реализации отдельного свойства класса типа mystr.count , который может вычислятся и в констукторе класса при инициализации, и непосредственно при запросе.. опять таки все зависит от каждой конкретной реализации класса String и требований, которые к нему предъявляются...

Отредактировано..
З.Ы. Сорри, не ту цитату добавил 1й раз smile

Добавлено @ 20:25 
Цитата(Void @ 15.12.2006,  20:01)
выяснилось, что длина массива хранится со смещением 4 байта от адреса объекта в памяти, дальше следует непосредственно содержимое массива.
JIT загнал адрес a в регистр, но поместить длину в регистр не догадался. Равно как и не догадался убрать проверку на выход за границу массива.

Длина строки хранится со смещением +8 байт.

2Void
Кстати, если ты решил разобраться с С и с выделением и управлением памятью  в С и т.д. и т.п., советую тебе почитать Страуструпа и любые издания, которые посвящены непосредственно базовому языку С, которые выходили года до 1995  smile или позднее, но исключительно по базовому языку С/С++. Он НУ ОЧЕНЬ СИЛЬНО отличается от С#, а компилятор для turbo C 3.x от того, который сделан в ВС2003/2005 и даже в  Borland С++Builder 4,5 непосредственно для базовых свойств(преобразование типов, прямой доступ к памяти и т.п....) которых мне так не хватает в C#..... 

З.Ы. 2Mr.DUDA СОРРРИИИИ за оффтоп  smile  неудержалси.... smile 

Это сообщение отредактировал(а) Yama - 15.12.2006, 20:16
--------------------
Если бы строители строили дома так же, как программисты пишут программы, то первый же залетевший в форточку дятел разрушил бы всю нашу цивилизацию.
PM MAIL   Вверх
Exception
Дата 15.12.2006, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 29
Всего: 186



Цитата(Yama @  15.12.2006,  21:12 Найти цитируемый пост)
Сама по себе строка, если изначально не определена как const - величина изменяемая


Товарищ, ошибаетесь.

Цитата(http://msdn2.microsoft.com/en-us/library/system.string.aspx)

A String object is called immutable (read-only) because its value cannot be modified once it has been created. Methods that appear to modify a String object actually return a new String object that contains the modification. If it is necessary to modify the actual contents of a string-like object, use the System.Text.StringBuilder class.

PM   Вверх
mr.DUDA
Дата 16.12.2006, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Yama
Цитата(Yama @  15.12.2006,  19:12 Найти цитируемый пост)
2VoidКстати, если ты решил разобраться с С и с выделением и управлением памятью  в С и т.д. и т.п., советую тебе почитать Страуструпа и любые издания, которые посвящены непосредственно базовому языку С, которые выходили года до 1995   или позднее, но исключительно по базовому языку С/С++. Он НУ ОЧЕНЬ СИЛЬНО отличается от С#, а компилятор для turbo C 3.x от того, который сделан в ВС2003/2005 и даже в  Borland С++Builder 4,5 непосредственно для базовых свойств(преобразование типов, прямой доступ к памяти и т.п....) которых мне так не хватает в C#....

Мы обсуждаем именно дотнетовскую реализацию String, а не сишную.
- string является неизменяемым объектом, сложение строк и substring создают новый объект, а не модифицируют буфер char-ов
- внутреннее представление строки - unicode (2 байта на символ), а не char

P.S. думаю, что Void хорошо знаком и с изданиями Страуструпа и проч., так что зря учить его пытаетесь  smile 



--------------------
user posted image
PM MAIL WWW   Вверх
Yama
Дата 18.12.2006, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 2.8.2006

Репутация: 2
Всего: 2



Exception
mr.DUDA
 smile  ААА... 
Каюсъ!!!!!!!
Ребят, чесслово не думал, что под .нет все настолько переделали smile , даже не переделали, а просто по другому сделали...  а Void"а не учу, просто посоветовал то, что в свое время сам читал. Мне как-то в библиотеке в моем вузе попалась книжка 1984 г. издания по С - прочитал и узнал много интересного. Жалко возвращать книгу было. Опять сорри за оффтоп  smile  .

*ушел учить .нет мат.часть........*
--------------------
Если бы строители строили дома так же, как программисты пишут программы, то первый же залетевший в форточку дятел разрушил бы всю нашу цивилизацию.
PM MAIL   Вверх
Дрон
Дата 18.12.2006, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 93



Цитата(mr.DUDA @  16.12.2006,  12:09 Найти цитируемый пост)
(2 байта на символ), а не char

Ну, э... вообще-то... char -- это и есть 2 байта smile


--------------------
Да. Именно так.
PM   Вверх
Yama
Дата 18.12.2006, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 2.8.2006

Репутация: 2
Всего: 2



Цитата(Дрон @ 18.12.2006,  12:38)
Цитата(mr.DUDA @  16.12.2006,  12:09 Найти цитируемый пост)
(2 байта на символ), а не char

Ну, э... вообще-то... char -- это и есть 2 байта smile

Но...... в .нет smile
http://msdn2.microsoft.com/en-us/library/system.string.aspx

Цитата

Each Unicode character in a string is defined by a Unicode scalar value, also called a Unicode code point or the ordinal (numeric) value of the Unicode character. Each code point is encoded using UTF-16 encoding, and the numeric value of each element of the encoding is represented by a Char object. 

A single Char object usually represents a single code point; that is, the numeric value of the Char equals the code point. However, a code point might require more than one encoded element. For example, a Unicode supplementary code point (a surrogate pair) is encoded with two Char objects.

Indexes
An index is the position of a Char object, not a Unicode character, in a String. An index is a zero-based, nonnegative number starting from the first position in the string, which is index position zero. Consecutive index values might not correspond to consecutive Unicode characters because a Unicode character might be encoded as more than one Char object. To work with each Unicode character instead of each Char object, use the System.Globalization.StringInfo class.


З.Ы. учу .нетматчасть smile 
--------------------
Если бы строители строили дома так же, как программисты пишут программы, то первый же залетевший в форточку дятел разрушил бы всю нашу цивилизацию.
PM MAIL   Вверх
mr.DUDA
Дата 18.12.2006, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(Дрон @  18.12.2006,  11:38 Найти цитируемый пост)
Ну, э... вообще-то... char -- это и есть 2 байта


Цитата(Yama @  18.12.2006,  12:15 Найти цитируемый пост)
Но...... в .нет


Дрон, а мы про С говорили, там 1 байт на char. У них есть двухбайтный аналог - short, unsigned short или wchar_t.


--------------------
user posted image
PM MAIL WWW   Вверх
Дрон
Дата 18.12.2006, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 93



Цитата(mr.DUDA @  18.12.2006,  14:08 Найти цитируемый пост)
а мы про С говорили, там 1 байт на char

Цитата(mr.DUDA @  16.12.2006,  12:09 Найти цитируемый пост)
Мы обсуждаем именно дотнетовскую реализацию String, а не сишную.

Брр... Совсем запутался smile
Ну ладно. Не буду встревать в чужие темы  smile 




--------------------
Да. Именно так.
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1478 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.