Производительность метода расширения - PullRequest
8 голосов
/ 17 июня 2009
            /*I have defined Extension Methods for the TypeX like this*/ 
        public static Int32 GetValueAsInt(this TypeX oValue)
        {
            return Int32.Parse(oValue.ToString());
        }
        public static Boolean GetValueAsBoolean(this TypeX oValue)
        {
            return Boolean.Parse(oValue.ToString());
        }


         TypeX x = new TypeX("1");
         TypeX y = new TypeX("true");


         //Method #1
         Int32 iXValue = x.GetValueAsInt();
         Boolean iYValue = y.GetValueAsBoolean();

         //Method #2
         Int32 iXValueDirect = Int32.Parse(x.ToString());
         Boolean iYValueDirect = Boolean.Parse(y.ToString());

Не увлекайтесь TypeX, говоря, что я должен определять эти методы внутри TypeX, а не в Extension). У меня нет контроля над ним (Actual Class I определил, что он находится в SPListItem.

Я хотел преобразовать TypeX в Int или Boolean, и эта операция - одна из распространенных вещей, которую я выполняю во многих местах кода. Я хотел знать, не приведет ли это к снижению производительности. Я пытался интерпретировать код IL с помощью Reflector, но у меня это не получается. Может быть, для приведенного выше примера не будет никакого снижения производительности. В общем, я хотел бы узнать о последствиях в отношении производительности при использовании методов расширения.

Ответы [ 4 ]

24 голосов
/ 17 июня 2009

Методы расширения: просто изменение времени компиляции с:

x.GetValueAsBoolean()

до

Extensions.GetValueAsBoolean(x)

Это все, что нужно - преобразовать то, что похоже на вызов метода экземпляра, в вызов статического метода.

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

РЕДАКТИРОВАТЬ: IL, в соответствии с просьбой ...

Взяв этот образец:

using System;

public static class Extensions
{
    public static void Dump(this string x)
    {
        Console.WriteLine(x);
    }
}

class Test
{
    static void Extension()
    {
        "test".Dump();
    }

    static void Normal()
    {
        Extensions.Dump("test");
    }
}

Вот IL для Extension и Normal:

.method private hidebysig static void  Extension() cil managed
{
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "test"
  IL_0006:  call       void Extensions::Dump(string)
  IL_000b:  nop
  IL_000c:  ret
} // end of method Test::Extension

.method private hidebysig static void  Normal() cil managed
{
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "test"
  IL_0006:  call       void Extensions::Dump(string)
  IL_000b:  nop
  IL_000c:  ret
} // end of method Test::Normal

Как видите, они точно такие же.

4 голосов
/ 17 июня 2009

Методы расширения - это просто компилятор voodoo, поэтому они имеют все последствия для производительности обычных методов во время выполнения.

2 голосов
/ 17 июня 2009

Вы не будете страдать от производительности, поскольку все методы расширения связаны во время компиляции (как вы это скажете?).

1 голос
/ 17 июня 2009

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

...