[.Net] Насколько медленнее вызывать свойство объекта напрямую и через

6yrop

через PropertyInfo.GetValue
Вообще reflection работает медленно, но я думаю, в основном это из-за поиска по методанным, а если уже найдено свойство и интересует только время его вызова.

yolki

Это ты к чему?
Builder? Delphi? property вроде только в них..
насколько мне известно, на вызов property тратится на одно разнаименование указателя больше, чем при вызове метода (или доступа к члену).
ок, после редактирования, вопрос снят.

bastii

Если свойчтва не виртуальные, то раздница огромная, т.к. прямые вызовы инлайнятся. Хотя и очень большая в лучае виртуальных. Если хочется динамически со свойствами быстро работать, то можно написать свой витульный метод типа GetPropertyValueFromName(String name). Тогда, если свойств мало, то в реализации метода будет немного ифов.

bastii

чтобы было еще быстрее, можно свойства занумеровать

bastii

Если хочешь делать чрез рефлекшион, то лучше запоминать не PropertyInfo,а MethodInfo соответстующего get метода, а то в GetValue делают примерно так:
  
MethodInfo mi = this.GetGetМethod;
mi.Invoke(...);

bastii

а вообще много чего можно придумать
вроде неплохой вариант держать делегат на GetGetMethod свойства (в вер 2.0 эту должно быть заметно быстрей, чем через MethodInfo.Invode)
еще можно по старинке только одними интерфейсами обойтись (только гемора много)

rosali

Блин, да не надо программируя на .Net думать о скорости отдельных команд, надо думать о скорости алгоритма, и то не очень сильно. С чего вы взяли, что JIT не может проинлайнить вызовы рефлексии? что он не научится этому через год? Вместо того чтобы написать _понятную_ программу давайте ее уродовать, чтобы она _чуть-чуть_ быстрее работала на _текущей_ версии рантайма, пипец

6yrop

Блин, да не надо программируя на .Net думать о скорости отдельных команд, надо думать о скорости алгоритма, и то не очень сильно
на практике оказывается не все так хорошо. У нас писали, используя рефлекшен, не очень большой по объему вычислений алгоритм, однако наблюдаются явные тормоза, говорят это именно из-за рефлекшена.
p.s. провел простенький эксперимент, разница во времени между прямым вызовом и через рефлекшен 2-3 порядка

6yrop

да я уже встречал мнение о том, что рефлекшен тормозит
web-страница
Для отображения колонок таблицы на поля и свойства нашего объекта используется механизм Reflection, единственным недостатком которого является некоторая нерасторопность.

bastii

в версии 1.0 разработчики откровенно забили на производительность рефлексии, они сами так говорят
уже в версии 2.0 многое заметно станет быстрее
но больше всего в .NET используются делегаты, вот их в первую очередь и оптимизировали в версии 2.0
а до рефлексии не факт, что скоро руки у них дойдут ведь если очень надо, то всегда можно сделать быстро используя фактори, делегаты и кэшируя метаданные
это как с эксепшионами, throw будет со временем становится все дороже и дороже относительно остального в .NET

edmsk

Я тут недавно писал довольно большой проект при поддержке Microsoft Research!
Проеект был связан с написанием транслятора кода на языке .NET в ассмеблер видеокарточки - чтобы можно было шейдеры писать на языках платформы. Так вот - умные люди меня заверили, что вызовы вроде FiledInfo.SetValue SetValueDirect GetValue работают также как обычные проперти. Самыми дорогостоящими операциями являются this.GetType и всякие разнообразные поиски внутри типа.
В проекте Reflection используется один раз на кадр для проставления параметров в видеокарточку, снижения производительности при этом (я имею в виде в сравнении прямыми обращениями без Reflection) не наблюдается!

6yrop

Так вот - умные люди меня заверили, что вызовы вроде FiledInfo.SetValue SetValueDirect GetValue работают также как обычные проперти.
попробуй повызывать проперти в большом цикле, разница в два порядка

edmsk

Так вот - попробовал. Естественно если просто вызывать пропрти на Get_value, то копмилятор это выбросит из кода. Соответственно надо что-нить с ним сделать, с полученным значением-то.
Так вот - заходи на dunhil//ReflectionTest - там прога лежит - время прри достаточном количестве лругих операций отличается на 10-20 миллисекунд!
Хотя это опять-таки не показатель. И в каждом конкретном случае можно получать разные данные.

6yrop

папки такой нет.
отличается на 10-20 миллисекунд!
вообще-то надобы относительную оценку

rosali


class A
{
public int x;
public A(int _x)
{
x = _x;
}
}

class C
{
private A _a;

public A a
{
get
{
return(_a);
}
set
{
_a = value;
}
}
}

class MainClass
{

[STAThread]
static void Main(string[] args)
{
PropertyInfo pi = typeof(C).GetProperty("a");
int N = 1000000;
C[] cs = new C[N];
for(int i=0; i<N; i++)
cs[i] = new C;
A a1 = new A(1);
A a2 = new A(2);

DateTime t1 = DateTime.Now;
for(int i=0; i<N; i++)
cs[i].a = a1;

DateTime t2 = DateTime.Now;
for(int i=0; i<N; i++)
pi.SetValue(cs[i], a2, null);

DateTime t3 = DateTime.Now;

System.Console.WriteLine(t2-t1);
System.Console.WriteLine(t3-t2);
System.Console.ReadLine;
}
}

00:00:00.0500720
00:00:17.8256320
Так что пока оценка в 2 порядка подтверждается...
Причем пример написан так, что видно, что причина не в boxing-е (int-ов, например)

edmsk

Ну я имею в виду что Reflection конечно медленней работает, но если достаточно сложные вещи допролнительно делаются то на это моэно забивать

bastii

только пометь свойство атрибутом, чтобы не делалась инлайн, а то совсем нечестно

rosali

Ерунда, что в этом нечестного-то? Пусть inline-ит, если может... Нам же надо узнать насколько медленнее обычные программы будут работать при использовании рефлексии, и что-то я сомневаюсь, что в них программисты помечают чего-то там аттрибутом ради чесности

bastii

это я к тому, что в нормальных программах так тупо не используют рефлексию в циклах, а свойства часто виртуальные
Оставить комментарий
Имя или ник:
Комментарий: