Информация об изменениях

Сообщение Re[21]: Тормознутость и кривость linq от 21.03.2016 14:09

Изменено 21.03.2016 14:10 Serginio1

Здравствуйте, alex_public, Вы писали:


S>>Для примера вызов нетовского метода из 1С через Ireflect составляет на моем старом ноутбуке 20 000 вызовов в секунду.

S>>http://infostart.ru/public/448668/

_>50 мкс? Жутко много (это же сотни тысяч ассемблерных инструкций!). Ну и при построение sql из linq будут десятки обращение к рефлексии.

Угу это вызов из интерпритатора. Упаковка и распаковка данных между манагед и унманагед кодом и на древнем ноутбуке.

 public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
        {        // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)

            if (name == "[DISPID=-4]")
            {
                IEnumVARIANT rez = new EnumVariantImpl(((System.Collections.IEnumerable)O).GetEnumerator());
                  return rez;
             
            }


            object[] args = ПолучитьМассивРеальныхОбъектов(argsOrig);

            culture = CultureInfo.InvariantCulture;



            // Invoke whatever needs be invoked!
            object obj;

            try
            {

                if (T.IsEnum && !((invokeAttr & BindingFlags.InvokeMethod) == BindingFlags.InvokeMethod))
                    return ОбернутьОбъект(Enum.Parse(T, name));


                //           if (ЭтоСемерка)
                ПроверитьНаДоступКПолям(ref invokeAttr, args.Length);


                if (ЭтоТип)
                    obj = T.InvokeMember(name, invokeAttr, binder, null, args, modifiers, culture, namedParameters);
                else if (ЭтоExpandoObject)
                {
                    if (invokeAttr.HasFlag(BindingFlags.InvokeMethod) && МетодыObject.ContainsKey(name))
                        obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
                    else
                        obj = InvokeMemberExpandoObject(name, invokeAttr, args);
                }
                else
                    obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);

            }
            catch (Exception e)
            {
                ПоследняяОшибка = e;
                string Ошибка = "Ошибка в методе " + name + " " + e.Message + " " + e.Source;
  
                if (e.InnerException != null)
                    Ошибка = Ошибка + "\r\n" + e.InnerException.ToString();

                if (ВыводитьСообщениеОбОшибке)
                { 
                MessageBox.Show(Ошибка);
                MessageBox.Show(e.StackTrace);
                MessageBox.Show(invokeAttr.ToString());
                }
                throw new COMException(Ошибка);
            }

            // Так как параметры могут изменяться (OUT) и передаются по ссылке
            // нужно обратно обернуть параметры
            УстановитьИзмененияВМассиве(argsOrig, args);

            return ОбернутьОбъект(obj);
        }
Здравствуйте, alex_public, Вы писали:


S>>Для примера вызов нетовского метода из 1С через Ireflect составляет на моем старом ноутбуке 20 000 вызовов в секунду.

S>>http://infostart.ru/public/448668/

_>50 мкс? Жутко много (это же сотни тысяч ассемблерных инструкций!). Ну и при построение sql из linq будут десятки обращение к рефлексии.

Угу это вызов из интерпритатора. Упаковка и распаковка данных между манагед и унманагед кодом и на древнем ноутбуке.
Да еще внутри куча вызовов.

 public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
        {        // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)

            if (name == "[DISPID=-4]")
            {
                IEnumVARIANT rez = new EnumVariantImpl(((System.Collections.IEnumerable)O).GetEnumerator());
                  return rez;
             
            }


            object[] args = ПолучитьМассивРеальныхОбъектов(argsOrig);

            culture = CultureInfo.InvariantCulture;



            // Invoke whatever needs be invoked!
            object obj;

            try
            {

                if (T.IsEnum && !((invokeAttr & BindingFlags.InvokeMethod) == BindingFlags.InvokeMethod))
                    return ОбернутьОбъект(Enum.Parse(T, name));


                //           if (ЭтоСемерка)
                ПроверитьНаДоступКПолям(ref invokeAttr, args.Length);


                if (ЭтоТип)
                    obj = T.InvokeMember(name, invokeAttr, binder, null, args, modifiers, culture, namedParameters);
                else if (ЭтоExpandoObject)
                {
                    if (invokeAttr.HasFlag(BindingFlags.InvokeMethod) && МетодыObject.ContainsKey(name))
                        obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
                    else
                        obj = InvokeMemberExpandoObject(name, invokeAttr, args);
                }
                else
                    obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);

            }
            catch (Exception e)
            {
                ПоследняяОшибка = e;
                string Ошибка = "Ошибка в методе " + name + " " + e.Message + " " + e.Source;
  
                if (e.InnerException != null)
                    Ошибка = Ошибка + "\r\n" + e.InnerException.ToString();

                if (ВыводитьСообщениеОбОшибке)
                { 
                MessageBox.Show(Ошибка);
                MessageBox.Show(e.StackTrace);
                MessageBox.Show(invokeAttr.ToString());
                }
                throw new COMException(Ошибка);
            }

            // Так как параметры могут изменяться (OUT) и передаются по ссылке
            // нужно обратно обернуть параметры
            УстановитьИзмененияВМассиве(argsOrig, args);

            return ОбернутьОбъект(obj);
        }