Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [General] Большое кол-во параметров у подпрограммы, как можно решить эту проблему 
:(
    Опции темы
Traum
Дата 13.3.2011, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 30.1.2004

Репутация: нет
Всего: нет



Проблема: подпрограмма имеет очень большое количество входных и выходных параметров.

Пример:
subroutine CalcSomething( ParamIn1, ParamIn2, ParamIn3, ParamIn4,&
                          ParamIn5, ParamIn6, ParamIn7, ParamIn8,&
                          ParamIn9, ParamIn10, ParamIn11, ParamIn12,&
                          ParamIn13, ParamIn14, ParamIn15, ParamIn16,&
                          
                          ParamOut1, ParamOut2, ParamOut3, ParamOut4,&
                          ParamOut5, ParamOut6, ParamOut7, ParamOut8,&
                          ParamOut9, ParamOut10, ParamOut11, ParamOut12,&
                          ParamOut13, ParamOut14, ParamOut15, ParamOut16 )
 
end subroutine

В принципе все работает. Однако при каждом вызове данной подпрограммы приходится таскать за собой весь
этот огород параметров. Например часто в цикле требуется вызывать подобную подпрограмму, когда изменяется
всего один из входных параметров (все остальные остаются прежними), и проверять всего один из выходных параметров.
Тем не менее всегда требуется указывать все параметры - что сильно раздувает код и делает его нечитабельным.
Кроме того я подозреваю, что при каждом вызове подобной подпрограммы, фортран вынужден копировать все эти многочисленные
параметры (или многочисленные ссылки на каждый из этих параметров), что будет сильно тормозить выполнение программы.
Выход можно было бы найти в следующем: создать структурный тип:

type TStruct
  ! входные параметры
  real ParamIn1
  real ParamIn2
  real ParamIn3
  ...
  real ParamIn30
  ! выходные параметры
  real ParamOut1 
  real ParamOut2 
  real ParamOut3 
  ...         
  real ParamOut30
end type


subroutine CalcSomething( Struct )
  type(TStruct) Struct


end subroutine

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

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

Как поступают программисты в подобных случаях?

Это сообщение отредактировал(а) Traum - 13.3.2011, 18:55
PM MAIL   Вверх
Фантом
Дата 13.3.2011, 19:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 5
Всего: 49



В принципе, подобное количество параметров (неоднородных) - явное свидетельство плохого проектирования программы. Соответственно, самый правильный вариант - подумать, как без этого обойтись.

Если никак не придумывается, то можно воспользоваться и структурами. Можно объявлять параметры с модификатором OPTIONAL - это необязательный аргумент, в процедуре можно предусмотреть все возможные варианты, а фактически вызывать с теми, которые требуются. Разделение входных и выходных параметров делается модификаторами INTENT(IN) и INTENT(OUT).
PM   Вверх
kemiisto
Дата 13.3.2011, 19:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: нет
Всего: 160



Цитата(Traum @  13.3.2011,  16:52 Найти цитируемый пост)
Кроме того я подозреваю, что при каждом вызове подобной подпрограммы, фортран вынужден копировать все эти многочисленные
параметры (или многочисленные ссылки на каждый из этих параметров), что будет сильно тормозить выполнение программы.

Это уж как ты захочешь. Машина - лишь формальный исполнитель твоей воли. smile 

Цитата(Traum @  13.3.2011,  16:52 Найти цитируемый пост)
Как поступают программисты в подобных случаях?

У программистов подобных случаев возникать не должно (по крайней мере, на этапе кодирования). У тебя проблемы не с кодированием, а с проектированием. Тот факт, что ты не можешь абстрагироваться и выделит некие сущности, которые бы выступили в роли структур данных в твоей программе говорит именно об этом. 

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

Ты не проектировал структуры данных, ты о них даже не думал, судя по кол-ву аргументов твоих процедур. За что боролся, на то и напоролся.

Цитата(Traum @  13.3.2011,  16:52 Найти цитируемый пост)
Причем при вызове подпрограммы принимающей всего одну структурную переменную, можно ожидать что фортран не будет заниматься копированием
каждого из параметров, а передаст лишь только одну ссылку на структурную переменную, что увеличить скорость.

Откуда ты набрался этих "ожиданий"? В стандарте языка такая информация отсутствует. И ещё раз - как ты захочешь, так и будет. В каком-то смысле. Кстати, уж коли зашла об этом речь, то стандарт языка Fortran вообще не оговаривает способ передачи аргументов в процедуры.

Цитата(Traum @  13.3.2011,  16:52 Найти цитируемый пост)
Но в этом случае возникают другие трудности, связанные с тем. что в других подпрограммах данную структуру следовало бы оформлять по иному
(другие входные, другие выходные параметры, часть параметров может оказаться ненужной, или часть параметров потребуется добавить)
При этом теряется контроль над тем какие параметры являются входными, а какие выходными.

Я мало что понял из этого куска текста.

Но.

Во-первых, ты слышал что-нибудь про функции (FUNCTION)? Передаём в кач-ве параметра одну структуру данных, получаем в качестве возвращаемого значения другую. Твой вариант с огромной структурой, содержащей и входные, и выходные параметры, + вызов процедуры, пожалуй не лучший.

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

В-третьих, можно заюзать ООП для получения определённых преимуществ. Но тут надо смотреть, стоит ли игра свеч.

Вообще, надо смотреть задачу. Так из общих оснований сложно ответить. Классику бы надо почитать в любом случае. Дейкстра, Вирт, ...

Добавлено через 1 минуту и 44 секунды
Цитата(Фантом @  13.3.2011,  17:21 Найти цитируемый пост)
В принципе, подобное количество параметров (неоднородных) - явное свидетельство плохого проектирования программы. 

Опоздал. smile 


--------------------
PM MAIL WWW GTalk Jabber   Вверх
Фантом
Дата 13.3.2011, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 5
Всего: 49



Цитата(kemiisto @  13.3.2011,  19:22 Найти цитируемый пост)

В-третьих, можно заюзать ООП для получения определённых преимуществ. Но тут надо смотреть, стоит ли игра свеч.

Как правило, не стоит. ООП само по себе может быть полезно, но в области применения Фортрана это случается крайне редко. А вот, например, модули тут, возможно, и помогут (хотя я все равно не верю в необходимость гонять 30+ разнородных параметров в процедуру и обратно).
PM   Вверх
Traum
Дата 13.3.2011, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 30.1.2004

Репутация: нет
Всего: нет



Спасибо, что посоветовали почитать Дейкстра, Вирта. Некоторые ответы я не понял, особенно это:
Цитата

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


что за структуры данных и именно на языке Fortran (это type?)

Цитата

А вот, например, модули тут, возможно, и помогут (хотя я все равно не верю в необходимость гонять 30+ разнородных параметров в процедуру и обратно).


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

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

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

Цитата

можно заюзать ООП для получения определённых преимуществ. Но тут надо смотреть, стоит ли игра свеч.

На Fortranе это очень умопомпрачительно (покрайней мере на компиляторах, поддерживающих 95-й стандарт)

Это сообщение отредактировал(а) Traum - 13.3.2011, 21:50
PM MAIL   Вверх
Фантом
Дата 13.3.2011, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 5
Всего: 49



Цитата(Traum @  13.3.2011,  21:48 Найти цитируемый пост)
На входе получается определенное количество конструктивных данных, далее данные по температуре, давлению, расходу и составу одной среды и тоже самое для второй среды. На выходе должны быть данные по температуре и давлению для выходящих потоков, массогабаритные характеристики теплообменника. Короче получается столько параметров, что мало не покажется.

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

...
 call subrout(param1=3,param3=6)
...

subroutine subrout
  implicit none
  integer,optional :: param1,param2,param3,param4

  if(present(param4)) then
    ...
  else 
    ...
  end if
....

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Fortran | Следующая тема »


 




[ Время генерации скрипта: 0.0630 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.