Как максимизировать производительность собственного R-скрипта (который будет выполняться тысячи раз)? [закрытый]


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

Мои вопросы таковы:

  1. является ли нижеприведенный план для этого хорошим?
  2. можете ли вы придумать какой-нибудь способ выжать из него больше скорости (без перезаписи собственных функций R, хотя я согласен с копированием подмножества их внутреннего кода и запуском только этого, а не всей функции)?

План

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

Каждая вызываемая функция будет находиться в отдельной строке, в согласованном формате, в порядке зависимости (в том смысле, что, например, cox.zph зависит от уже существующего объекта coxph, поэтому coxph() будет вызываться раньше, чем cox.zph()). Функции будут обернуты в try() , и если функция не работает, то вывод и функции, зависящие от него, сначала проверяют, имеет ли возвращаемый объект try-error свой первый класс, и если да, то какое-то значение заполнителя.

За блоком вызываемых функций следует длинный оператор c(), в котором каждый элемент извлекается из соответствующих объектов fit в отдельной строке. Здесь также, если исходный объект оказывается try-error или заполнителем, поместите NA в этот выходной слот.

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

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

Несколько Более Конкретных Последующих Вопросов

  1. Если я уже использую compilePKGS(T) и enableJIT(3) (из встроенной библиотеки compiler), Есть ли что-то еще, что можно получить, запустив вручную compile() или cmpfun() на моей функции-оболочке и интерпретируемые функции, которые он вызывает?
  2. есть ли у кого-нибудь рекомендации по выбору наилучшего значения enableJIT(), или, если меня не волнует время запуска, "чем больше, тем лучше"?
  3. Если каждое моделирование-это новая случайная величина, я ничего не выиграю от запоминания, верно?
  4. для длительных задач мне нравится, чтобы внутренняя функция проверяла, существует ли файл с заданным именем, и если да, то отправляла его в свою среду. Это позволяет мне восстановить контроль над сеансом на муха, чтобы исправить проблемы, запустить browser(), сохранить внутренние объекты и т. д. без необходимости прерывать весь пробег. Но, я думаю, что пингинг файловой системы, которая часто начнет складываться. Существует ли консенсус относительно наиболее эффективного способа передачи логического значения (т. е. исходного кода сценария отладки или нет) запущенному процессу R (под Linux)?

Спасибо.

1 2

1 ответ:

Это, скорее всего, будет касаться только части ваших вопросов. Мне повезло ускорить процессы, избежав также функции apply. применение не векторизовано и на самом деле занимает довольно много времени. Я видел выгоды, используя вложенные операторы ifelse ().

Вы пробовали Rprof()? Это было полезно в моем случае для идентификации медленных элементов моего кода. Не решение само по себе, а полезная диагностика.