Каковы преимущества/недостатки использования ключевого слова params vs. List в качестве входных данных для некоторой функции C#?C#: ключевое слово params vs. list
В основном, что такое производительность соображения и другие компромиссы.
Каковы преимущества/недостатки использования ключевого слова params vs. List в качестве входных данных для некоторой функции C#?C#: ключевое слово params vs. list
В основном, что такое производительность соображения и другие компромиссы.
PARAMS ключевого слова синтаксический сахар обрабатывается компилятор С #. под капотом, это фактически превращая
void Foo(params object[] a) { ... }
Foo(1,2,"THREE");
в
void Foo(object[] a) { ... }
Foo(new object[] { 1, 2, "THREE" })
С производительности точки зрения, как вы просите о, вызов PARAMS просто быстрее, потому что это немного быстрее, чтобы создать массив, чем для создания списка <>. Между этими двумя фрагментами нет разницы в производительности.
параметры ключевых слов позволяет динамически передавать переменное количество аргументов функции, не заботясь об ошибках компиляции, как это:
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%, но я думаю, что техническое различие - это просто синтаксический сахар - в любом случае вы действительно передаете массив любых введите параметр.
насчет проблем с производительностью? –
Это не та проблема, о которой вы действительно должны беспокоиться о производительности - я уверен, что во всем, что вы рассматриваете, есть проблемы с большими проблемами производительности. Производительность практически такая же, из-за того, что (я думаю), что это в основном только синтаксис компилятора и не имеет ничего общего с тем, как сама функция вызывается, когда она находится в IL. –
Ну, с PARAMS ключевое слово можно ввести аргументы в метод как это:
MethodName(1, 2, 3, 4);
Но со списком, вы могли бы сделать это следующим образом:
MethodName(new List<int> {1, 2, 3, 4});
с синтаксисом может быть немного более ясным в первом, чем последнее. Это полезно, когда вы только один параметр, чтобы передать в:
// params
MethodName(1);
// List
MethodName(new List<int> {1});
Что касается проблем с производительностью? –
Ну, params
позволяет красивее синтаксис при вызове его, но список (предполагается, что вы имеете в виду IList<>
) является более гибким, поскольку различные классы могут реализовывать интерфейс. Передача List<>
имеет смысл только в том случае, если вам необходимо выполнить определенные операции в списке, которые не поддерживаются интерфейсом (например, ToArray()
).
как насчет проблем с производительностью? –
Что с ними? –
+1 для IList
params
- это языковая конструкция для функций с переменным числом параметров. Это похоже на спецификатор C elipses - то есть printf(char* fmt, ...)
. Язык поддерживает эту операцию, может также использовать ее, особенно если это упрощает чтение кода.
Лично я бы пропустил параметры. Меня укусили один или два раза. Как? Позволь мне объяснить.
Вы пишете публичный метод с этой подписью:
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");
Также параметры «пахнут», как он часто используется для Interop. –
Ну, у вас не было бы этой проблемы, если бы вы сгруппировали определенные члены в одном объекте, например 'Credentials'. –
Dynami, вы абсолютно правы. Плохой код ... плохое использование параметров. –
Основное различие между этими двумя, что я могу видеть, что число параметров, передаваемых в метод устанавливается во время компиляции, используя params
, в то время как с List<T>
это зависит от списка принятого в во время выполнения.
Независимо от того, следует ли фиксировать количество аргументов, с которыми должен быть вызван ваш метод во время компиляции, - это pro или con, полностью зависит от вашего дизайна и намерения. Либо может быть полезным в зависимости от того, чего вы надеетесь достичь.
Params
помогает на фронте читабельности и находится как можно ближе к необязательному параметру, который вы собираетесь использовать в C#. Я бы использовал только реализацию List<T>
, если мне нужно было использовать неизвестное количество параметров в любой точке.
Редактировать: просто заметили ваши изменения в отношении проблем с производительностью. По этой теме я не уверен, хотя, если вы могли бы ожидать большого количества «параметров», используя List<T>
, тогда как у params
есть защитный колпачок на нем из-за того, что они должны быть закодированы.
Лично я использую 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);
}
}
Это потому, что время создания списка медленное. если вы вызываете метод, который принимает IEnumerable, скажем, строку [] вместо списка
Уверен, но это не имеет значения! –
Производительность программиста Иногда ваш метод иногда может быть улучшен за счет использования ключевых слов params.
(Учитывая, что программисты стоят столько более компьютеров, почему вы думаете о любом другом виде деятельности.)
Если мы передадим существующий список ссылок, тогда будет медленнее использовать параметры из-за накладных расходов на выделение памяти для массива. –
@Mert: Но вам также пришлось выделить память для списка <>, который вы передаете как ссылку ... –
@ZeCarlos, но я предположил, что List уже «существует». –