Объект получил в 2010 VB тот же optimalization как динамичный в C# 4.0?

Некоторые люди утверждали, что функция C# 4.0 представила с dynamic ключевое слово совпадает с, "все - Объектная" функция VB. Однако любой запрос к динамической переменной будет переведен в делегата однажды и с тех пор, делегата позвонят. В VB, при использовании Object, никакое кэширование не применяется, и каждый запрос к невведенному методу включает большое отражение под капотом, иногда всего огромную 400-кратную потерю производительности.

Имеет динамическая оптимизация делегата типа и кэширующийся также добавленный к VB невведенные вызовы метода, или VB's не вводится Объект, все еще настолько медленный?

6
задан Abel 13 April 2010 в 09:29
поделиться

3 ответа

Решение

Некоторое исследование и лучшее чтение , ранее упомянутого в статье , упомянутой Хансом Пассантом, приводит к следующему выводу:

  • VB.NET 2010 поддерживает DLR;
  • Вы можете реализовать IDynamicMetaObjectProvider , если хотите явно поддерживать динамику, компилятор VB.NET обновлен, чтобы распознавать это;
  • VB Object будет использовать DLR и кэширование методов, только если объект реализует IDynamicMetaObjectProvider ;
  • Типы BCL и Framework не реализуют IDynamicMetaObjectProvider , использование Object для таких типов или ваших собственных типов вызовет классические, не- кешированный VB.NET с поздним связыванием.

Предпосылки: уточнение того, почему кеширование с поздним связыванием может помочь производительности кода VB.

Некоторые люди (среди которых Ханс Пассант, см. Его ответ) могут задаться вопросом, почему кеширование или отсутствие кеширования при позднем связывании может иметь значение. На самом деле, это имеет большое значение как в VB, так и в других технологиях позднего связывания (помните IQueryInterface с COM?).

Позднее связывание сводится к простому принципу: учитывая имя и его объявления параметров, перебрать в цикле все методы этого класса и его родительских классов с помощью методов, доступных через интерфейс Type ( а в VB метод, свойство и поле могут выглядеть одинаково, что делает этот процесс еще медленнее). Если вы считаете, что таблицы методов неупорядочены, то это намного дороже, чем один прямой (т. Е. Типизированный) вызов метода.

Если бы вы могли найти метод один раз, а затем сохранить указатель метода в таблице поиска, это значительно ускорило бы этот процесс. Привязка кэшированного метода в DLR идет на один шаг дальше и заменяет вызов метода указателем на фактический метод, если это возможно. После первого вызова это становится на порядок быстрее для каждого последующего вызова (подумайте, в 200-800 раз быстрее).

В качестве примера того, когда это имеет значение, вот код, который иллюстрирует эту проблему. В случае, когда каждый класс имеет строковое свойство .Name , но классы не имеют общего предка или интерфейса, вы можете наивно отсортировать списки любого из этих типов следующим образом:

' in the body of some method '
List<Customers> listCustomers = GetListCustomers()
List<Companies> listCompanies = GetListCompanies()

listCustomers.Sort(MySort.SortByName)
listCompanies.Sort(MySort.SortByName)

' sorting function '
Public Shared Function SortByName(Object obj1, Object obj2) As Integer
    ' for clarity, check for equality and for nothingness removed '    
    return String.Compare(obj1.Name, obj2.Name)    
End Function

Этот код ( по крайней мере, похожий) фактически был запущен в производство с одним из моих клиентов и использовался в часто называемом обратном вызове AJAX. Без ручного кэширования свойств .Name , уже в списках среднего размера, содержащих менее полумиллиона объектов, код с поздним связыванием стал настолько заметным бременем, что в конечном итоге привел к остановке всего сайта. Отследить эту проблему оказалось непросто, но это уже история для другого раза. После исправления этой проблемы сайт восстановил 95% ресурсов процессора.

Итак, ответ на вопрос Ханса «разве у вас нет больших проблем, о которых стоит беспокоиться?» прост: это большая проблема (или может быть), особенно. программистам VB, которые слишком небрежно подошли к использованию позднего связывания.

В этом конкретном случае и во многих подобных случаях VB.NET 2010, по-видимому, не был обновлен для введения позднего связывания, и поэтому Object остается злом для тех, кто не знает, и его не следует сравнивать с динамическим .

PS: проблемы с производительностью позднего связывания очень сложно отследить, если у вас нет хорошего профилировщика производительности и вы не знаете, как позднее связывание реализовано внутри компилятора.

5
ответ дан 17 December 2019 в 00:06
поделиться

Хороший вопрос. Я предполагаю, что ответ - «Нет», потому что в этой статье в журнале MSDN говорится, что VB.Net был изменен для поддержки среды выполнения динамического языка, и кратко описаны изменения в среде выполнения, но не упоминается кеширование. .

Кто-нибудь знает лучше?

0
ответ дан 17 December 2019 в 00:06
поделиться

Цитата из статьи о новых возможностях :

Visual Basic 2010 обновлен для полной поддержки DLR в его latebinder

Ничего более явного, чем это. Это DLR, который реализует кеширование.

2
ответ дан 17 December 2019 в 00:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: