Saleh Salehizadeh
Saleh Salehizadeh
خواندن ۱ دقیقه·۶ سال پیش

نوشتن کد با سرعت اجرای بیشتر با rcpp برای R

در مورد زبان‌های سطح بالایی مثل R یا متلب، همیشه توصیه می‌شه که از قابلیت‌های built-in استفاده کنید. مثلا فرض کنید می‌خوایم ضرب داخلی دو بردار با طول مساوی رو پیاده‌سازی کنیم. اول بگم که ضرب داخلی برای دو بردار هم‌طول و برابر با مجموع ضرب عضوهای نظیر تعریف می‌شه. حالا برای این‌کار به شکل معمول داریم:

x = c(1,2,5) y= c(5,3,1) sum(x*y)

و خروجی به شکل:

output:[1]16

به دست میاد. اما خیلی وقتا می‌خوایم کاری انجام بدیم که به‌طور طبیعی با اعمال داخلی R قابل انجام نیست. یعنی نمی‌شه به شکل برداری نوشتشون. اون‌وقت لازمه از روش‌های تکراری مثل حلقه‌ی for یا while استفاده کنیم:

output = 0 for (i in c(1:3)){ output = output + x[i] * y[i] }


اما استفاده از for در زبان‌های سطح بالا به هیچ‌وجه کار بهینه‌ای نیست. و سرعت اجرای برای داده‌های بزرگ‌تر توی اونا به‌شدت کمه و ممکنه شما رو برای حجم زیاد داده‌ها ناکام بذاره.

خب چه می‌شه کرد؟

بذارین این سوال رو با یه سوال دیگه هم روبرو کنیم. پکیج‌های R رو که گاها پر از الگوریتمای پیچیده است و نمی‌شه به‌راحتی برداری کرد و پیاده‌سازیشون نیاز به استفاده از مواردی مثل حلقه‌های for داره رو چطور پیاده‌سازی می‌کنن که اینقدر سریع اجرا می‌شن.
جواب اینه که پکیج‌های R عمدتا با c++ و fortran نوشته می‌شن و توی R به شکل shared object استفاده می‌شن.
چطور می‌تونیم خودمون این کارو بکنیم؟

خیلی ساده است. با استفاده از پکیج Rcpp توی R می‌شود کد c++ رو برای R کامپایل کرد. برای استفاده از این پکیج اول اونو نصب می‌کنیم:

install.packages('Rcpp')

به همین سادگی. حالا شما این بسته رو که فراخوانی کنید می‌تونید ازش استفاده کنید و به کمکش کد c++تون رو کامپایل کنید و استفاده کنید:

library('Rcpp')

برای مثال:

library(Rcpp) cppFunction( "int test(NumericVector X, NumericVector Y){ int len = X.size(); int output = 0; for (int i=0; i<len; i++){ output += X[i] * Y[i]; } return (output); }") test(x,y)


و خروجی برابر همون مقدار 16 خواهد بود. اما این‌بار با سرعت اجرای بالاتر از forهای R.
همین کار رو می‌تونید تو یه فایل جدا انجامش بدید و با دستور ‍‍sourceCpp فراخوانیش کنید.
در کل این پکیج بیشتر از یه پست وبلاگی زمان‌بره و توصیه می‌کنم داکیومنت‌های این پکیج رو بخونید و یه نگاهی هم به مثال‌ها بندازید.

همواره اگه اصلاحی برا نوشته‌های من دارید خوشحال می‌شم ببینم.







rآماردیتاساینسبرنامه‌نویسی
شاید از این پست‌ها خوشتان بیاید