Kecepatan komputasi dalam R?

16

Saya telah ditugaskan untuk memindahkan salah satu model stokastik besar kami saat ini dari SAS dan ke bahasa baru. Secara pribadi, saya lebih suka bahasa kompilasi tradisional, tetapi PI ingin saya memeriksa R, yang saya tidak pernah gunakan. Motivasi kami untuk mengeluarkan model dari SAS adalah (1) banyak orang tidak memiliki akses ke sana karena SAS mahal, (2) kami ingin menjauh dari bahasa yang ditafsirkan, dan (3) SAS lambat untuk jenis model yang kita miliki.

Untuk (1), jelas R memenuhi kebutuhan untuk bebas. Untuk (2), idealnya, kami ingin membuat executable, tetapi R biasanya digunakan sebagai bahasa skrip. Saya melihat bahwa seseorang baru-baru ini mengeluarkan kompiler R - apakah ini telah diterima dengan baik? Apakah mudah digunakan? Kami lebih suka tidak memaksa pengguna untuk mengunduh R sendiri. Untuk (3), masalah kita dengan SAS adalah semua waktu yang dihabiskan dalam penulisan I / O dan membaca set data. Model kami intensif secara komputasi, dan kami sering dibatasi oleh runtime. (mis. Tidak biasa bagi seseorang untuk membajak komputer orang selama akhir pekan untuk menjalankan.) Kami memiliki model serupa yang dibangun di Fortran yang tidak memiliki masalah yang sama karena semua pekerjaan dilakukan dalam memori. Bagaimana cara kerja R? Apakah akan sama dengan SAS, dalam hal ia bekerja di datasteps, membaca dan menulis file? Atau bisakah ia melakukan manipulasi array dalam memori?

Melissa
sumber
Anda biasanya dapat mempercepat sas dengan melakukan semua pekerjaan Anda dalam satu langkah data tunggal. Ini akan mengurangi waktu I / O, karena Anda secara efektif hanya membaca data satu kali. Menggunakan banyak prosedur juga akan memperlambat Anda. Misalnya, jika Anda memodelkan berulang kali memanggil proc glm atau proc logistik (katakanlah untuk bootstrap), lebih cepat untuk membuat kumpulan data besar dan menggunakan pernyataan per kata daripada memanggil banyak panggilan proc (katakanlah menggunakan makro% lakukan loop). jika Anda memprogram dengan baik, Anda seharusnya tidak mengalami masalah waktu berjalan karena membaca dan mengeluarkan file (setidaknya tidak lebih dari perangkat lunak lain
probabilityislogic
Selain itu Anda dapat menggunakan array sementara dalam langkah-langkah data sas dengan cara yang mirip dengan bagaimana Anda akan menggunakan matriks dalam R.
probabilityislogic

Jawaban:

18

R bekerja di memori - jadi data Anda perlu masuk ke memori untuk sebagian besar fungsi.

Paket kompiler, jika saya memikirkan hal yang Anda pikirkan ( paket kompiler Luke Tierney disertakan dengan R), bukan hal yang sama dengan bahasa yang dikompilasi dalam pengertian tradisional (C, Fortran). Ini adalah kompiler byte untuk R dalam arti bytecode Java yang dieksekusi oleh Java VM atau kompilasi byte dari kode LISP Emacs. Itu tidak mengkompilasi kode R ke dalam kode mesin tetapi lebih mempersiapkan kode R ke dalam bytecode sehingga dapat digunakan lebih efisien daripada kode R mentah untuk ditafsirkan.

Perhatikan bahwa jika Anda telah membentuk Fortran dengan baik, Anda mungkin memiliki yang terbaik dari kedua dunia; R dapat memanggil rutin Fortran yang dikompilasi.

Pasang kembali Monica - G. Simpson
sumber
Terima kasih! Sangat menyenangkan mengetahui bahwa saya dapat memiliki grafik R yang hebat dan memanggil rutin Fortran yang dikompilasi. Ini mungkin jawabannya!
Melissa
2
Hanya untuk memperluas catatan Gavin tentang memori: lihat bagian tentang Memori Besar dalam tampilan tugas CRAN ini jika Anda bekerja dengan kumpulan data yang lebih besar: cran.r-project.org/web/views/HighPerformanceComputing.html
Brandon Bertelsen
1
Juga berpikir bahwa penting untuk dicatat bahwa Rcpp kemungkinan dapat digunakan untuk mendapatkan peningkatan kinerja secara bertahap.
Brandon Bertelsen
Rcpp berguna untuk membungkus C ++ untuk digunakan dalam / dengan R. Ini membantu proses (sangat) tetapi masih menggunakan alat dasar R untuk memanggil kode yang dikompilasi. Jika OP sudah memiliki kode Fortran atau keterampilan Fortran, Rcpp mungkin kurang bermanfaat.
Pasang kembali Monica - G. Simpson
13

Saya telah menggunakan SASselama 15 tahun, dan telah mulai menggunakan dengan Rserius selama 6 bulan terakhir, dengan beberapa bermain-main di dalamnya selama beberapa tahun sebelumnya. Dari perspektif pemrograman, R apakah manipulasi data secara langsung, tidak ada yang setara denganDATA atau PROC SQLprosedur karena mereka tidak diperlukan (yang terakhir menjadi lebih efisien SASketika ada banyak manipulasi data yang harus dilakukan dari sumber data eksternal, misalnya data administrasi). Ini berarti bahwa, sekarang saya mengerti, manipulasi data lebih cepat Rdan memerlukan kode jauh lebih sedikit.

Masalah utama yang saya temui adalah memori. Tidak semua paket R mengizinkan WEIGHTspesifikasi tipe, jadi jika Anda memiliki SASdataset dengan variabel yang digunakan di FREQatauREPLICATE pernyataan, Anda mungkin memiliki masalah. Saya telah melihat paket ffdan bigmemorydalam R tetapi tampaknya tidak kompatibel dengan semua paket R, jadi jika Anda memiliki kumpulan data yang sangat besar yang memerlukan analisis yang relatif tidak umum, dan telah dikumpulkan, Anda mungkin memiliki masalah dengan memori.

Untuk otomatisasi, jika Anda punya SAS macros Anda harus dapat memprogram yang setara Rdan dijalankan sebagai batch.

Untuk pengkodean R, saya menggunakan Notepad++dan mengatur bahasa R, dan sekarang saya menemukan kegembiraanR Studio . Kedua produk ini gratis, dan melakukan markup bahasa seperti SASGUI sintaksis yang ditingkatkan (Saya hanya pernah menggunakan layar sintaksis dalam SAS).

Ada situs , dan buku yang terkait, untuk orang-orang swapping dari SASke R. Saya menemukan mereka berguna untuk mencoba mencari cara menerjemahkannyaSAS perintah R.

Update: satu hal yang membuat saya gila ketika datang ke Radalah bahwa Rtidak menganggap segala sesuatu adalah kumpulan data ( data framedalam Ristilah), karena itu bukan paket statistik dalam cara yang SAS, SPSS, Stata, dll. Jadi, misalnya, butuh beberapa saat untuk membuat ifpernyataan berfungsi karena saya terus mendapatkan bantuan untuk ifpernyataan dengan vektor (atau mungkin matriks) sedangkan saya membutuhkan ifpernyataan yang bekerja dengan data frames. Jadi halaman bantuan mungkin perlu dibaca lebih dekat dari biasanya, karena Anda harus memeriksa bahwa perintah yang ingin Anda lakukan akan beroperasi dengan tipe objek data yang Anda miliki.

Bit yang masih membuatku gila ketika mempelajari Rperintah baru (misalnya metode analisis dalam paket kontribusi) adalah bahwa bantuan untuk perintah sering tidak sepenuhnya mandiri. Saya akan pergi ke halaman bantuan untuk mencoba mempelajari perintah dan catatan penggunaan sering ...terkandung di dalamnya. Kadang-kadang mencoba mencari tahu apa yang bisa atau harus pergi ke tempat yang ...telah membawa saya ke dalam lingkaran rekursif. Singkatnya relatif dari catatan bantuan, yang SASdarinya memberikan contoh terperinci sintaks dan contoh yang berhasil dengan penjelasan studi dalam contoh, adalah kejutan yang cukup besar.

Michelle
sumber
2
+1 Silakan pertimbangkan untuk memperbarui utas meta kami tempat kami mengumpulkan tautan ke sumber daya perangkat lunak statistik. Ada satu jawaban untuk R dan satu lagi untuk SAS: keduanya akan mendapat manfaat dari memiliki tautan ke r4stats.com. (Utas itu sebenarnya adalah bagian dari FAQ kami. Kami berharap agar tetap terkini dan bermanfaat.)
whuber
1
R juga memiliki paket yang mendukung akses SQL melalui driver RODBC atau SQLite.
DWIN
1
Saya setuju dengan komentar Anda tentang bantuan R. Saya sebenarnya menunjukkan apa yang Anda katakan di salah satu milis R beberapa tahun yang lalu. Responsnya tidak positif. Dalam keadilan, saya (a) mungkin tidak mengekspresikan diri saya dengan sangat baik, dan tidak memberikan contoh nyata dan (b) tidak mengejar masalah ini. Sebagai rangkuman, masalah 1 adalah contoh yang terlalu rumit dan melibatkan terlalu banyak konsep yang tidak terkait. Contoh rumit adalah OK tetapi harus mengikuti contoh sederhana. Masalah 2 adalah bahwa hampir tidak ada penjelasan atau penjelasan tentang apa yang dilakukan contoh.
Faheem Mitha
Mengenai "bantuan" R mengingatkan pada sesuatu yang dikatakan bos saya kepada saya. "Anda belajar R dengan melakukannya dengan seseorang yang sudah tahu R duduk di sebelah Anda di depan komputer"
probabilityislogic
Dan untuk semua orang ada buku dan Stack Overflow. Ya, belajar R sendiri cukup sulit, setidaknya bagi saya.
Michelle
10

R adalah bahasa pemrograman. Ini tidak bekerja di datasteps. Ia melakukan apa pun yang Anda ingin lakukan, karena itu hanya bahasa pemrograman, seorang budak untuk keinginan Anda, diekspresikan dalam bahasa kurung keriting dan titik dua.

Anggap saja seperti Fortran atau C, tetapi dengan vektorisasi implisit sehingga Anda tidak perlu mengulang array, dan manajemen memori dinamis sehingga Anda tidak perlu malloc () atau mendeklarasikan ukuran array kapan saja.

Sebagian besar melakukan semua pekerjaannya di memori, tetapi jika Anda ingin membaca bagian dari file di, mung itu, lalu memuntahkan beberapa hasilnya, dan membaca bit berikutnya, yah, Anda teruskan dan menulis program R yang apakah itu.

Anda menentang diri Anda dengan mengatakan bahwa model ini intensif secara komputasi, tetapi SAS lambat karena I / O ... Yang satu atau yang lain pasti ...

Jika Anda sudah memiliki sesuatu yang serupa di Fortran, dan Anda mengatakan Anda ingin pindah dari bahasa yang ditafsirkan, lalu mengapa tidak melakukannya di Fortran juga?

Kompiler R dapat menyebabkan beberapa peningkatan, tetapi jika kode R Anda ditulis dengan baik, Anda tidak akan mendapatkan sesuatu yang terlalu besar - tidak seperti menulisnya dalam C atau Fortran.

Spacedman
sumber
Ah, saya tidak menjelaskan diri saya dengan baik. Ini intensif dalam manipulasi dataset, yang dalam SAS, berarti terlalu banyak waktu yang dihabiskan di I / O. Saran awal saya adalah Fortran, tetapi PI tertarik pada kami beralih ke R, jadi dia ingin saya memeriksanya. Terima kasih!
Melissa
7

Saya mengerti bahwa secara default SAS dapat bekerja dengan model yang lebih besar dari memori, tetapi ini tidak terjadi dengan R, kecuali jika Anda secara khusus menggunakan paket seperti biglm atau ff.

Namun, jika Anda melakukan pekerjaan array di R yang dapat di-vectorised itu akan sangat cepat - mungkin setengah dari kecepatan program C dalam beberapa kasus, tetapi jika Anda melakukan sesuatu yang tidak dapat di-vector, maka itu akan tampak cukup lambat. Untuk memberi Anda sebuah contoh:

# create a data.frame with 4 columns of standard normally distributed RVs
N <- 10000

# test 1
system.time( {df1 <- data.frame(h1=rnorm(N),
                h2=rpois(N, lambda=5),
                h3=runif(N),
                h4=rexp(N))
} )
# about 0.003 seconds elapsed time

# vectorised sum of columns 1 to 4
# i.e. it can work on an entire column all at once
# test 2
system.time( { df1$rowtotal1 <- df1$h1 + df1$h2 + df1$h3 + df1$h4 })
# about 0.001 seconds elapsed time

# test 3
# another version of the vectorised sum
system.time( { df1$rowtotal2 <- rowSums(df1[,c(1:4)]) })
# about 0.001 seconds elapsed time

# test 4
# using a loop... THIS IS *VERY* SLOW AND GENERALLY A BAD IDEA!!! :-)
system.time( {
        for(i in 1:nrow(df1)) {
                df1$rowtotal3 <- df1[i,1]+ df1[i,2] + df1[i,3] + df1[i,4]
        }
} )
# about 9.2 seconds elapsed time

Ketika saya meningkatkan N dengan faktor sepuluh hingga 100.000, saya menyerah pada tes 4 setelah 20 menit, tetapi tes 1: 3 masing-masing mengambil 61, 3 dan 37 mili- detik

Untuk N = 10.000.000 waktu untuk pengujian 1: 3 adalah 3.3s, 0.6s dan 1.6s

Perhatikan bahwa ini dilakukan pada laptop i7 dan pada 480mb untuk N = 10million, memori tidak menjadi masalah.

Untuk pengguna di windows 32-bit ada batas memori 1,5gb untuk R tidak peduli berapa banyak memori yang Anda miliki, tetapi tidak ada batasan untuk windows 64-bit atau 64-bit linux. Memori hari ini sangat murah dibandingkan dengan biaya satu jam waktu saya, jadi saya hanya membeli lebih banyak memori daripada menghabiskan waktu untuk menyiasati ini. Tetapi ini mengasumsikan bahwa model Anda akan sesuai dengan memori.

Sean
sumber
1
(+1) Terima kasih karena menawarkan ilustrasi yang bermanfaat, Sean!
whuber
3

(2), idealnya, kami ingin membuat yang dapat dieksekusi, tetapi R biasanya digunakan sebagai bahasa skrip

Ya, dan ini adalah alasan bagus untuk pindah ke R. Minat menulis paket R adalah untuk memungkinkan pengguna untuk dengan mudah membuat fungsi Anda berinteraksi dengan alat lain yang disediakan oleh R, misalnya memberi mereka data bootstraped ... atau apa pun yang mereka mau. Jika menurut Anda ini tidak penting, tetap gunakan C / C ++ atau bahasa kompilasi favorit Anda.

Saya ingin menambahkan peringatan: Anda sudah menjadi programmer, belajar R akan mudah dan cepat; belajar pemrograman R yang efisien akan lebih lama. Karena R ditafsirkan, konstanta disembunyikan dalamHAI()dari kompleksitas asimptotik bisa besar atau kecil ... misalnya, jika Anda tertarik menjalankan data Anda, Anda akan menggunakannya rle(), itu akan cepat (ini adalah fungsi yang dikompilasi sebelumnya). Jika Anda skrip algoritma yang sama persis, itu akan lambat (itu akan ditafsirkan). Ini adalah contoh dasar: Anda memiliki banyak trik menggunakan vektor dan matriks, untuk menghindari loop ditafsirkan dan membuat fungsi yang dikompilasi melakukan semua pekerjaan.

Jadi berhati-hatilah. Setelah percobaan pertama Anda, Anda pasti akan merasa jijik dengan R, karena Anda akan menemukannya lambat, dengan sintaks aneh, dll. Setelah Anda mengetahuinya, itu bisa menjadi alat yang sangat efisien. Anda bahkan dapat mengakhiri dengan menulis metode Anda dalam R sebagai fase awal untuk pengkodean C / C ++. Tahap akhir adalah mempelajari API R untuk membuat fungsi yang dikompilasi, dan Anda akan menjadi pemandu R :)

Elvis
sumber
2

Manipulasi array dalam memori adalah hal besar bagi SAS, tampaknya. Saya tidak tahu secara spesifik tentang R, tetapi saya menduga bahwa R beroperasi dalam memori secara default, karena paket memori yang diperluas untuk R, ff dan bigmemory, memindahkan data dari memori ke disk. Saya punya petunjuk untuk Anda jika Anda ingin meningkatkan kecepatan atau penggunaan memori. Untuk meningkatkan kecepatan, Anda harus terlebih dahulu menggunakan R sebagaimana dimaksud, yaitu: membuat vektor kode Anda dan menggunakan kompilasi kode byte. (Juga: hindari operasi penyalinan memori sebanyak mungkin.) Kedua, gunakan kode profiler yang disediakan Rprof () untuk mengidentifikasi tambalan lambat dalam kode Anda, dan tulis ulang dalam C atau C ++ jika perlu. Jika Anda membutuhkan lebih banyak memori, Anda dapat menggunakan argumen loncatan di fungsi read.table () untuk membaca sepotong data sekaligus dan Anda juga dapat menggunakan paket seperti RMySQL, yang menambahkan utilitas manipulasi basis data ke R. Jika Anda masih membutuhkan lebih banyak memori dan mampu menurunkan kecepatan secara bersamaan, Anda dapat menggunakan paket salju untuk menjalankan R secara paralel. (Anda dapat menemukan detail tentang ini, dan banyak lagi, dalam buku "The Art of R Programming", oleh Norman Matloff, yang diterbitkan pada akhir tahun lalu. Rincian tentang paket yang disebutkan di sini dapat ditemukan online).

Jean-Victor Côté
sumber