- •Конспект лекций по курсу «Сети эвм» Часть 2 Сурков д.А.
- •Сравнительная характеристика технологий .Net и Java
- •Общее для Java и .Net.
- •Управление памятью в .Net
- •Процедурные типы данных (делегаты)
- •Динамические массивы
- •Многозадачность
- •1: Добавление в очередь ThreadPool нового делегата, который будет запускаться в отдельном потоке (из пула свободного потока). Делегат отработал – поток обратно в пул.
- •Исключительные ситуации
- •Шаблоны в с# (появились недавно в .Net 2.0)
- •В с# в шаблонах введено понятие итератора.
- •Массивы
- •Метод Get в SystemArray
- •Средства удалённого вызова .Net Remoting
- •Пользовательские атрибуты
- •Inherited – будем ли создавать атрибут для наследника.
- •Защищённые информационные системы. Технология “Эльбрус”
- •Защищенная файловая система
Динамические массивы
Динамические массивы – лучшая структура данных. Дерево удобно для быстрого поиска, данные отсортированы (лучше сбаллансированное дерево).
Поиск по этому дереву занимает наименьшее время.
A занимает в памяти: буква – 8 байт + 4 байта на левый указатель + 4 байта правый указатель. Чтобы дерево балансировать, нужны указатели вверх, т.е. еще + 4 байта. Элемент, обычно, указатель на какие-то данные.
Если просто массив отсортирован, применяем поиск делением отрезка пополам (время поиска примерно такое же).
Т.е. дерево – 4 указателя, массив – один указатель (в четыре раза меньше).
При поиске по массиву данные лежат компактно, значит в КЭШ попадает сразу несколько.
При вставке элементов возникают трудности: дерево надо балансировать, а для массива при вставке в середину сдвигаются большие блоки памяти. Но, так как операции сдвига больших блоков памяти очень эффективны (специальные команды процессора), массив лучше.
Недостаток массивов: если массив очень большой и надо вставлять элемент в начало, то массив проигрывает дереву. Но если мы в массиве пометим позицию, до которой массив отсортирован, а добавляем только в конец:
то когда добавление закончено, выполняем сортировку.
Можно сделать две границы. Если превысим вторую, то выполняем сортировку:
Т.к. это случается один раз в 100 или 1000 элементов, то массив эффективнее.
Пример:
public delegate int PositionChanged (Point pos); // это делегат
public class PositionChanged: System.MultiCastDelegate // в это превращается
{ // делегат компилятором
public PositionChanged (Object target, Int32 MethodPtr) // конструктор
{
base (target, MethodPtr, null); // указатель на объект, на
// метод, на предыдущий
} // делегат
public int virtual Invoke (Point pos) // метод для вызова делегата
{
if (_prev != null)
_prev.Invoke (pos); // рекурсия (вызов предыдущего делегата в
// цепочке)
return _target._MethodPtr (pos); // псевдоход
} // в программе это будет как _MethodPtr (_target, pos);
public virtual IasyncResult BeginInvoke (Point pos, AsyncCallback callback, Object
obj);
public virtual void EndInvoke (IAsyncResult result);
} // class
делегат превращается в класс, который наследуется от MultiCastDelegate (класса ссылочного типа). Этот класс создает компилятор.
если в объекте:
(значение _ prev ===null)
(в .Net поле PositionChanged – это указатель на объект)
BeginInvoke для асинхронного вызова делегатов (вызова делегатов в
отдельном потоке без ожидания его завершения )
EndInvoke
BeginInvoke – запускает делегат в отдельном потоке и тут же возвращает управление
EndInvoke – позволяет дождаться завершения делегата
Таким образом, делегат в программе представляет собой создание объекта MultiCastDelegate и заполнение его полей. Сохраняется указатель на динамически созданный объект.
В .Net любое конструирование динамических объектов (с помощью new) – это такая же эффективная операция, как и создание объектов на стеке, т.к. это инкремент текущей позиции в нулевом поколении.
(в Delphi экземпляр типа PositionChanged – запись)
Базовый класс Object:
namespace System
{
public class Object
{
public Object ( );
public virtual BooleanEquals (Object obj);
public virtual Int32 GetHashCode ( );
public Type GetType ( );
public virtual string ToString ( );
protected virtual void Finalise ( );
protected Object MemberviseClone ( );
}
}
эти методы – у любого объекта
Equals – сравнивает два объекта. Он вызывается для оператора GetHashCode – 32-х разрядное число для определения Hash-кода объекта. Наиболее эффективная структура для поиска – массивы и хеш-таблицы. Хеш-таблицы – тот же массив, но индекс – это номер в хеш-таблице.
GetType –ссылка на метаданные для объекта
Finalise – если не предопределен, то он выбрасывается
MemberviseClone – копия объекта без внутренних членов
a = b
b=MemberviseClone(a);
т.е. частичная копия объекта (создание верхнего уровня).
Чтобы на системном уровне копированием блоков создавать объекты
ToString ( ) - представление объекта как строки