Я пытаюсь оптимизировать часть кода и озадачен информацией из 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) обернуть определенные операции внутри других функций и посмотреть, когда эти функции появляются в стеке вызовов. Последний способ неэлегантен, но кажется, что это лучший способ добавить метку в стек вызовов. Первый способ неприятен тем, что для выполнения кода требуется довольно много времени, а итеративно раскомментировать код и запустить его заново - неприятно.