2015-08-19 8 views
3

Что такое наиболее эффективный (с точки зрения скорости обработки и использования памяти) метод для передачи большого количества пользовательских входных переменных в качестве аргументов функции и для возврата нескольких результатов?Самый эффективный способ передать несколько аргументов функции?

Длинная строка аргументов и возвращаемых значений каждый раз, когда я вызываю функцию - например. (a, b, c, d, e, f, g) = MyFunction (a, b, c, d, e, f, g) - кажется неэлегантным, и я предполагаю, что это также неэффективно; особенно если мне нужно вызвать функцию повторно или рекурсивно.

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

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

Предыдущее обсуждение по StackExchange: Elegant way to pass multiple arguments to a function рекомендовал использовать struct вместо векторов/массивов для передачи нескольких аргументов. Почему этот метод предпочитает использовать массивы, и в какой момент эффективность экономии оправдывает дополнительную сложность использования структуры?

Есть ли какие-либо другие методы, которые я должен рассмотреть, которые будут работать в Python или C/C++? (например, я новичок в объектно-ориентированное программирование, но интересно, если это может предложить решение, которое специфично в Python?)

Большое спасибо

+2

Обычно вы бы передать структура, содержащая аргументы. Вы можете передать кортеж, я полагаю (более идиоматично для C++, но все еще не совсем там, на мой взгляд). – Robinson

+4

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

+0

Передача в кортеж или dict или собственный пользовательский объект – muddyfish

ответ

2

Все это зависит от целевой системы и ее вызывающего соглашения для функций. Этот ответ относится только к C и C++.

Как правило, использование переменных области файла обычно является самым быстрым. В таких случаях переменная никогда не должна объявляться глобальной (доступной во всем проекте), а как статическая (доступная только локальному файлу).

По-прежнему следует избегать таких переменных в области переменных статического файла по нескольким причинам: они могут сделать код более трудным для чтения и обслуживания, недисциплинированное использование может привести к «коду спагетти», они создадут проблемы с повторным подключением, и они добавят некоторые дополнительные идентификаторы в пространство имен области файлов.

Следует отметить, что в случае ограниченности числа параметров сохранение их в виде отдельных параметров может повысить производительность, поскольку компилятор может затем сохранить некоторые из них в регистрах ЦП вместо их хранения в стеке. Регистры CPU - это самый быстрый способ передачи параметров функции. Как это работает, очень специфично для системы. Однако, записывая вашу программу таким образом, что вы надеетесь получить параметры, переданные через регистры процессора, в большинстве случаев представляет собой предварительную зрелую оптимизацию.

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

Причина, по которой структура/класс предпочтительнее, чем массив, просто потому, что переменные вместе образуют уникальный тип, но также и потому, что они, вероятно, будут иметь разные типы по сравнению друг с другом. Создание массива переменных, все из которых имеют разные типы, не имеет никакого смысла.

И в C++, класс предлагает другие преимущества по сравнению с массивом, например, конструкторы и деструкторы, пользовательские операторы присваивания и т.д.

0

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

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

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

В примере, который вы указали, существует несколько переменных разных типов. Вот почему структура предпочтительна, потому что для массива требуется, чтобы все параметры имели один и тот же тип. В python вы можете использовать named tuple для хранения переменной.

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