Копание в информации профилирования R

Я пытаюсь оптимизировать часть кода и озадачен информацией из summaryRprof(). В частности, похоже, что происходит несколько вызовов внешних программ на C, но я не могу определить, какая программа на C, из какой функции R. Я планирую решить эту проблему путем нарезки кода на кусочки и кубики, но мне интересно, не упускаю ли я из виду какой-то лучший способ интерпретации данных профилирования.

Самая высокопотребляющая функция - .Call, которая, по-видимому, является общим описанием для вызовов кода на C; следующие ведущие функции, похоже, являются операциями присваивания:

$by.self
                             self.time self.pct total.time total.pct
".Call"                        2281.0    54.40     2312.0     55.14
"[.data.frame"                  145.0     3.46      218.5      5.21
"initialize"                    123.5     2.95      217.5      5.19
"$<-.data.frame"                121.5     2.90      121.5      2.90
"as.vector"                     110.5     2.64      416.0      9.92

Я решил сосредоточиться на .Call, чтобы понять, как это возникает. Я просмотрел файл профилирования, чтобы найти записи с .Call в стеке вызовов, и вот верхние записи в стеке вызовов (по количеству появлений):

13640 "eval"
11252 "["
7044 "standardGeneric"
4691 "<Anonymous>"
4658 "tryCatch"
4654 "tryCatchList"
4652 "tryCatchOne"
4648 "doTryCatch"

Этот список ясен как грязь: и standardGeneric.

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

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

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

9
задан Iterator 27 September 2011 в 22:44
поделиться