2010-01-22 2 views
31

Каковы преимущества/недостатки использования ключевого слова params vs. List в качестве входных данных для некоторой функции C#?C#: ключевое слово params vs. list

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

ответ

33

PARAMS ключевого слова синтаксический сахар обрабатывается компилятор С #. под капотом, это фактически превращая

void Foo(params object[] a) { ... } 
Foo(1,2,"THREE"); 

в

void Foo(object[] a) { ... } 
Foo(new object[] { 1, 2, "THREE" }) 

С производительности точки зрения, как вы просите о, вызов PARAMS просто быстрее, потому что это немного быстрее, чтобы создать массив, чем для создания списка <>. Между этими двумя фрагментами нет разницы в производительности.

+0

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

+1

@Mert: Но вам также пришлось выделить память для списка <>, который вы передаете как ссылку ... –

+0

@ZeCarlos, но я предположил, что List уже «существует». –

2

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

public string PrefixFormatString(string p, string s, params object[] par) 
{ 
    return p + string.Format(s, par); 
} 
... 
PrefixFormatString("COM", "Output Error #{0} - Error = {1}", errNum, errStr); 

Если вы передадите список, вы должны построить список, прежде чем вы можете передайте его в:

public string PrefixFormatString(string p, string s, List<object> par) 
{ 
    return p + string.Format(s, par.ToArray()); 
} 
... 
List<object> l = new List<object>(new object[] { errNum, errStr }); 
PrefixFormatString("COM", "Output Error #{0} - Error = {1}", l); 

и он имеет тенденцию скрывать смысл того, какие данные функции ожидают.

Обратите внимание, что это очень похоже на прохождение простой переменной массива. Единственное различие заключается в том, что компилятор установит параметры в массив для вас ... Я не уверен на 100%, но я думаю, что техническое различие - это просто синтаксический сахар - в любом случае вы действительно передаете массив любых введите параметр.

+0

насчет проблем с производительностью? –

+2

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

0

Ну, с PARAMS ключевое слово можно ввести аргументы в метод как это:

MethodName(1, 2, 3, 4); 

Но со списком, вы могли бы сделать это следующим образом:

MethodName(new List<int> {1, 2, 3, 4}); 

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

// params 
MethodName(1); 

// List 
MethodName(new List<int> {1}); 
+0

Что касается проблем с производительностью? –

2

Ну, params позволяет красивее синтаксис при вызове его, но список (предполагается, что вы имеете в виду IList<>) является более гибким, поскольку различные классы могут реализовывать интерфейс. Передача List<> имеет смысл только в том случае, если вам необходимо выполнить определенные операции в списке, которые не поддерживаются интерфейсом (например, ToArray()).

+0

как насчет проблем с производительностью? –

+0

Что с ними? –

+0

+1 для IList или любого другого соответствующего интерфейса в зависимости от того, что должна делать ваша коллекция. –

0

params - это языковая конструкция для функций с переменным числом параметров. Это похоже на спецификатор C elipses - то есть printf(char* fmt, ...). Язык поддерживает эту операцию, может также использовать ее, особенно если это упрощает чтение кода.

0

Лично я бы пропустил параметры. Меня укусили один или два раза. Как? Позволь мне объяснить.

Вы пишете публичный метод с этой подписью:

public static void LogInUser(string username, string password, params string[] options) 

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

Теперь, через месяц вы хотите изменить свою подпись, чтобы добавить роль пользователя:

public static void LogInUser(string username, string password, string role, params string[] options) 

О, как все изменилось за что вызова метода.

LogInUser("[email protected]", "zz", "Admin", "rememberMe", "800x600"); 
+0

Также параметры «пахнут», как он часто используется для Interop. –

+4

Ну, у вас не было бы этой проблемы, если бы вы сгруппировали определенные члены в одном объекте, например 'Credentials'. –

+1

Dynami, вы абсолютно правы. Плохой код ... плохое использование параметров. –

0

Основное различие между этими двумя, что я могу видеть, что число параметров, передаваемых в метод устанавливается во время компиляции, используя params, в то время как с List<T> это зависит от списка принятого в во время выполнения.

Независимо от того, следует ли фиксировать количество аргументов, с которыми должен быть вызван ваш метод во время компиляции, - это pro или con, полностью зависит от вашего дизайна и намерения. Либо может быть полезным в зависимости от того, чего вы надеетесь достичь.

Params помогает на фронте читабельности и находится как можно ближе к необязательному параметру, который вы собираетесь использовать в C#. Я бы использовал только реализацию List<T>, если мне нужно было использовать неизвестное количество параметров в любой точке.

Редактировать: просто заметили ваши изменения в отношении проблем с производительностью. По этой теме я не уверен, хотя, если вы могли бы ожидать большого количества «параметров», используя List<T>, тогда как у params есть защитный колпачок на нем из-за того, что они должны быть закодированы.

23

Лично я использую params при написании функций, которые принимают ряд материалов, представленных другой программист (например String.Format), и IEnumerable при написании функций, которые принимают список элементов данных, предоставленных компьютер (например, File.Write).

Показатели производительности незначительны. Беспокойство о производительности тривиальной вещи, как это, это точно, о котором говорил Дональд Кнут в знаменитой цитате «преждевременной оптимизации - это корень всех злых».

Это сказал Аскер, кажется, зациклился на ней, так что здесь вы идете:

Результаты за 10 миллионов итераций:

params took 308 ms 
list took 879 ms 

Из этих результатов можно видеть, что массив PARAMS просто в два раза быстрее. Простой факт, что вы можете назвать любой из этих вещей Десять миллионов раз в секунду означает, что вы полностью теряете время, беспокоясь об этом. Используйте все, что лучше всего подходит вашему коду.

код, чтобы проверить его (компиляции и запуска в режиме выпуска с помощью VS2008)

class Program 
{ 
    const int COUNT = 10000000; 

    static IEnumerable<string> m_value = null; 

    static void ParamsMethod(params string[] args) 
    { m_value = args; } // do something with it to stop the compiler just optimizing this method away 

    static void ListMethod(List<string> args) 
    { m_value = args; } // do SOMETHING with it to stop the compiler just optimizing this method away 

    static void Main(string[] args) 
    { 
     var s = new Stopwatch(); 
     s.Start(); 
     for (int i = 0; i < COUNT; ++i) 
      ParamsMethod("a", "b", "c"); 

     Console.WriteLine("params took {0} ms", s.ElapsedMilliseconds); 

     s.Reset(); 
     s.Start(); 
     for (int i = 0; i < COUNT; ++i) 
      ListMethod(new List<string> { "a", "b", "c" }); 

     Console.WriteLine("list took {0} ms", s.ElapsedMilliseconds); 
    } 
} 
+0

Это потому, что время создания списка медленное. если вы вызываете метод, который принимает IEnumerable, скажем, строку [] вместо списка , производительность будет почти эквивалентна методу params. – Jimmy

+10

Уверен, но это не имеет значения! –

0

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

(Учитывая, что программисты стоят столько более компьютеров, почему вы думаете о любом другом виде деятельности.)

Смежные вопросы