ความเร็วในการคำนวณใน R?


16

ฉันได้รับมอบหมายให้ย้ายหนึ่งในโมเดล stochastic ที่มีขนาดใหญ่ในปัจจุบันของเราออกจาก SAS และเป็นภาษาใหม่ โดยส่วนตัวแล้วฉันชอบภาษาที่รวบรวมแบบดั้งเดิม แต่ PI ต้องการให้ฉันตรวจสอบ R ซึ่งฉันไม่เคยใช้ แรงจูงใจของเราในการนำโมเดลออกมาจาก SAS คือ (1) หลายคนไม่สามารถเข้าถึงได้เพราะ SAS มีราคาแพง (2) เรากำลังมองหาที่จะย้ายออกจากภาษาที่ตีความและ (3) SAS ช้าสำหรับ ประเภทของแบบจำลองที่เรามี

สำหรับ (1) เห็นได้ชัดว่า R ตอบสนองความต้องการที่จะให้เป็นอิสระ สำหรับ (2) เราควรจะสร้างไฟล์ที่เรียกทำงานได้ แต่โดยปกติแล้ว R จะใช้เป็นภาษาสคริปต์ ฉันเห็นว่ามีคนเพิ่งคอมไพเลอร์ R - ได้รับการตอบรับดีไหม? ใช้ง่ายไหม เราไม่ต้องการบังคับให้ผู้ใช้ดาวน์โหลด R เอง สำหรับ (3) ปัญหาของเรากับ SAS คือเวลาทั้งหมดในการเขียนและอ่านชุดข้อมูล I / O แบบจำลองของเรามีความเข้มข้นด้านการคำนวณและเรามักถูก จำกัด โดยรันไทม์ (เช่นไม่ใช่เรื่องแปลกสำหรับใครบางคนที่จะขโมยคอมพิวเตอร์ของผู้คนในช่วงสุดสัปดาห์เพื่อทำการวิ่ง) เรามีรูปแบบที่คล้ายกันที่สร้างขึ้นใน Fortran ที่ไม่มีปัญหาเดียวกันเพราะงานทั้งหมดทำในหน่วยความจำ R ทำงานอย่างไร มันจะเหมือนกับ SAS หรือไม่ในการทำงานกับ datasteps อ่านและเขียนไฟล์? หรือสามารถจัดการอาเรย์ในหน่วยความจำได้ไหม


โดยทั่วไปคุณสามารถเพิ่มความเร็ว sas ได้ด้วยการทำงานทั้งหมดในขั้นตอนเดียว สิ่งนี้จะลดเวลา I / O เนื่องจากคุณอ่านข้อมูลได้อย่างมีประสิทธิภาพเพียงครั้งเดียว การใช้ขั้นตอนมากมายจะทำให้คุณช้าลง ตัวอย่างเช่นถ้าคุณจำลองโทรหา proc glm หรือ proc logistic ซ้ำ ๆ (พูดถึง bootstrap) การสร้างชุดข้อมูลขนาดใหญ่และใช้คำสั่ง by เร็วกว่าการเรียกใช้ proc หลายสาย (พูดโดยใช้แมโคร% do loop) หากโปรแกรมของคุณดีคุณไม่ควรประสบปัญหาเวลาทำงานเนื่องจากการอ่านและส่งออกไฟล์ (อย่างน้อยไม่เกินกว่าซอฟต์แวร์อื่น ๆ
ความน่าจะเป็นทาง

นอกจากนี้คุณสามารถใช้อาร์เรย์ชั่วคราวในขั้นตอนข้อมูล sas ในทำนองเดียวกันกับวิธีที่คุณจะใช้เมทริกซ์ใน R.
ความน่าจะเป็นทาง

คำตอบ:


18

R ทำงานในหน่วยความจำ - ดังนั้นข้อมูลของคุณจำเป็นต้องพอดีกับหน่วยความจำสำหรับฟังก์ชั่นส่วนใหญ่

แพคเกจคอมไพเลอร์ถ้าฉันกำลังคิดถึงสิ่งที่คุณกำลังคิด ( แพคเกจคอมไพเลอร์ของ Luke Tierney ที่มาพร้อมกับ R) ไม่ใช่สิ่งเดียวกับภาษาที่คอมไพล์ในความหมายดั้งเดิม (C, Fortran) มันเป็นคอมไพเลอร์ไบต์สำหรับ R ในความรู้สึกของ Java bytecode ดำเนินการโดย Java VM หรือการรวบรวมไบต์ของรหัส Emacs LISP มันไม่ได้รวบรวมรหัส R ลงในรหัสเครื่อง แต่จะเตรียมรหัส R ลงในไบต์รหัสเพื่อให้สามารถใช้อย่างมีประสิทธิภาพมากกว่ารหัส R ดิบที่จะตีความ

โปรดทราบว่าถ้าคุณมี Fortran ที่ดีแล้วคุณก็น่าจะดีที่สุดในโลกทั้งคู่ R สามารถเรียกรูทีนที่รวบรวมไว้ของ Fortran ได้


ขอบคุณ! เป็นเรื่องดีที่ได้รู้ว่าฉันสามารถมีกราฟิค R ที่ยอดเยี่ยมและเรียกรูทีนที่รวบรวมไว้ของ Fortran นี่อาจเป็นคำตอบ!
Melissa

2
เพียงเพื่อขยายบันทึกย่อของ Gavin เกี่ยวกับหน่วยความจำ: ดูส่วนในหน่วยความจำขนาดใหญ่ในมุมมองงาน CRAN นี้หากคุณทำงานกับชุดข้อมูลขนาดใหญ่: cran.r-project.org/web/views/HighPerformanceComputing.html
Brandon Bertelsen

1
ยังคิดว่าเป็นเรื่องสำคัญที่จะต้องทราบว่า Rcpp น่าจะถูกใช้เพื่อเพิ่มประสิทธิภาพที่เพิ่มขึ้น
Brandon Bertelsen

Rcpp มีประโยชน์ในการห่อ C ++ เพื่อใช้ใน / กับอาร์ช่วยในกระบวนการ (อย่างมาก) แต่ยังคงใช้เครื่องมือพื้นฐานของ R เพื่อเรียกรหัสที่คอมไพล์ หาก OP มีรหัส Fortran หรือทักษะ Fortran แล้ว Rcpp อาจใช้งานน้อยกว่า
Reinstate Monica - G. Simpson

13

ฉันใช้มาSAS15 ปีแล้วและเริ่มใช้Rอย่างจริงจังในช่วง 6 เดือนที่ผ่านมาโดยมีบางส่วนอยู่ในนั้นเป็นเวลาสองปีก่อนหน้านั้น จากมุมมองการเขียนโปรแกรมR ทำการปรับเปลี่ยนข้อมูลโดยตรงไม่มีสิ่งใดเทียบเท่าDATAหรือPROC SQLขั้นตอนการทำงานเนื่องจากไม่จำเป็นต้องใช้ (หลังมีประสิทธิภาพมากขึ้นSASเมื่อมีการจัดการข้อมูลจำนวนมากที่ต้องทำจากแหล่งข้อมูลภายนอกเช่นข้อมูลการดูแลระบบ) ซึ่งหมายความว่าตอนนี้ฉันได้รับการแฮงค์การจัดการข้อมูลนั้นเร็วกว่าRและต้องการรหัสน้อยกว่ามาก

ปัญหาหลักที่ฉันพบคือหน่วยความจำ ไม่ใช่แพ็คเกจ R ทั้งหมดที่อนุญาตให้WEIGHTใช้ข้อกำหนดประเภทดังนั้นหากคุณมีSASชุดข้อมูลที่มีตัวแปรที่ใช้ในFREQหรือREPLICATEข้อความสั่งคุณอาจมีปัญหา ฉันดูที่ffและbigmemoryแพ็คเกจใน R แต่ดูเหมือนจะไม่เข้ากันได้กับแพ็คเกจ R ทั้งหมดดังนั้นหากคุณมีชุดข้อมูลขนาดใหญ่มากที่ต้องการการวิเคราะห์ที่ค่อนข้างแปลกและมีการรวบรวมคุณอาจมีปัญหากับหน่วยความจำ

สำหรับระบบอัตโนมัติถ้าคุณมีSAS macrosแล้วคุณควรจะสามารถเขียนโปรแกรมเทียบเท่าRและเรียกใช้เป็นชุด

สำหรับการเขียนโปรแกรมในR, ฉันถูกใช้Notepad++และการตั้งค่าภาษาและตอนนี้ฉันค้นพบความสุขของR R Studioผลิตภัณฑ์ทั้งสองนี้ให้บริการฟรีและทำเครื่องหมายภาษาเช่นเดียวกับSASไวยากรณ์ GUI ที่ได้รับการปรับปรุง(ฉันเคยใช้หน้าจอไวยากรณ์ในSAS)

มีเป็นเว็บไซต์และหนังสือที่เกี่ยวข้องกับการแลกเปลี่ยนสำหรับคนที่จากไปSAS Rผมพบว่าพวกเขามีประโยชน์สำหรับการพยายามที่จะทำงานออกวิธีการแปลบางคำสั่งลงไปSASR

ปรับปรุง: สิ่งหนึ่งที่ขับรถฉันถั่วเมื่อมาถึงRก็คือว่าRไม่ถือว่าทุกอย่างเป็นชุดข้อมูล ( data frameในRสำนวน) เพราะมันไม่ได้เป็นแพคเกจทางสถิติในทางที่SAS, SPSS, Stataฯลฯ ดังนั้นสำหรับตัวอย่างเช่นมันเอาฉันในขณะที่จะได้รับifงบการทำงานเพราะผมเก็บรับความช่วยเหลือสำหรับifงบกับเวกเตอร์ (หรืออาจเมทริกซ์) ในขณะที่ฉันจำเป็นต้องคำสั่งที่ทำงานร่วมกับif data framesดังนั้นหน้าความช่วยเหลืออาจจำเป็นต้องอ่านอย่างใกล้ชิดกว่าปกติเนื่องจากคุณจะต้องตรวจสอบว่าคำสั่งที่คุณต้องการจะทำงานกับประเภทวัตถุข้อมูลที่คุณมี

บิตที่ยังทำให้ฉันบ้าเมื่อเรียนรู้Rคำสั่งใหม่(เช่นวิธีการวิเคราะห์ในแพ็คเกจที่สนับสนุน) คือความช่วยเหลือสำหรับคำสั่งมักไม่ได้มีอยู่ในตัวเองทั้งหมด ฉันจะไปที่หน้าช่วยเหลือเพื่อพยายามเรียนรู้คำสั่งและมักจะมีบันทึกการใช้งาน...อยู่ในนั้น บางครั้งพยายามคิดออกสิ่งที่สามารถหรือควรไปในที่ที่มี...อยู่นำฉันเข้าสู่วงวนซ้ำ ความกะทัดรัดของบันทึกย่อความช่วยเหลือซึ่งมาจากSASตัวอย่างรายละเอียดของไวยากรณ์และตัวอย่างการทำงานพร้อมคำอธิบายของการศึกษาในตัวอย่างนั้นค่อนข้างน่าตกใจ


2
+1 โปรดพิจารณาอัปเดตเธรดของเราซึ่งเราได้รวบรวมลิงก์ไปยังแหล่งข้อมูลซอฟต์แวร์สถิติ มีหนึ่งคำตอบสำหรับ R และอีกคำตอบสำหรับ SAS: ทั้งคู่จะได้รับประโยชน์จากการมีลิงก์ไปยัง r4stats.com (หัวข้อนั้นเป็นส่วนหนึ่งของคำถามที่พบบ่อยของเราเราหวังว่าจะทำให้เป็นปัจจุบันและมีประโยชน์)
whuber

1
R ยังมีแพ็กเกจที่รองรับการเข้าถึง SQL ผ่านไดรเวอร์ RODBC หรือ SQLite
DWIN

1
ฉันเห็นด้วยกับความคิดเห็นของคุณเกี่ยวกับความช่วยเหลือ R จริง ๆ แล้วฉันชี้ให้เห็นถึงสิ่งที่คุณพูดในรายการส่งจดหมาย R รายการหนึ่งเมื่อหลายปีก่อน การตอบสนองนั้นไม่ดี ในความเป็นธรรมฉัน (a) อาจไม่ได้แสดงออกอย่างดีและไม่ได้ยกตัวอย่างที่เป็นรูปธรรมและ (b) ไม่ได้ติดตามเรื่องนี้ เพื่อสรุปปัญหา 1 เป็นตัวอย่างที่ซับซ้อนเกินไปและเกี่ยวข้องกับแนวคิดที่ไม่เกี่ยวข้องมากเกินไป ตัวอย่างที่ซับซ้อนคือตกลง แต่ควรทำตามตัวอย่างง่ายๆ ปัญหาที่ 2 คือเกือบจะไม่มีคำอธิบายประกอบหรือคำอธิบายว่าตัวอย่างทำอะไร
Faheem Mitha

เกี่ยวกับ R "ช่วย" เตือนสิ่งที่เจ้านายของฉันพูดกับฉัน "คุณเรียนรู้ R ด้วยการทำกับใครสักคนที่รู้แล้วว่า R นั่งถัดจากคุณที่คอมพิวเตอร์"
ความน่าจะเป็นทาง

และสำหรับคนอื่น ๆ ก็มีหนังสือและ Stack Overflow ใช่การเรียนรู้ด้วยตัวเองนั้นค่อนข้างยากอย่างน้อยก็เป็นเรื่องของฉัน
มิเชล

10

R เป็นภาษาโปรแกรม มันไม่ทำงานใน datasteps มันทำทุกสิ่งที่คุณต้องการให้ทำเพราะมันเป็นเพียงภาษาการเขียนโปรแกรมทาสสำหรับความต้องการของคุณแสดงเป็นภาษาของวงเล็บปีกกาและโคลอน

คิดว่ามันเหมือนกับ Fortran หรือ C แต่มี vectorisation โดยปริยายดังนั้นคุณไม่ต้องวนซ้ำอาร์เรย์และการจัดการหน่วยความจำแบบไดนามิกดังนั้นคุณจึงไม่ต้อง malloc () หรือประกาศขนาดอาร์เรย์ได้ตลอดเวลา

ส่วนใหญ่จะทำงานทั้งหมดในหน่วยความจำ แต่ถ้าคุณต้องการอ่านส่วนหนึ่งของไฟล์หมุนมันแล้วคายผลลัพธ์บางส่วนแล้วอ่านบิตถัดไปในดีคุณไปข้างหน้าและเขียนโปรแกรม R ที่ ทำอย่างนั้น

คุณขัดแย้งกับตัวเองในการบอกว่าแบบจำลองนั้นมีความเข้มข้นสูง แต่ SAS นั้นช้าเพราะ I / O ... อันใดอันหนึ่ง ...

หากคุณมีสิ่งที่คล้ายกันใน Fortran แล้วและคุณบอกว่าคุณต้องการย้ายออกไปจากภาษาที่ตีความแล้วทำไมไม่ทำเช่นนั้นใน Fortran ด้วย?

คอมไพเลอร์ R อาจทำให้เกิดความเร็วมากขึ้น แต่ถ้ารหัส R ของคุณเขียนได้ดีคุณจะไม่ได้อะไรที่ใหญ่เกินไป - ไม่ชอบเขียนใน C หรือ Fortran


อ่าฉันอธิบายตัวเองไม่ดี มีความเข้มข้นในการจัดการชุดข้อมูลซึ่งใน SAS หมายถึงเวลาที่ใช้ใน I / O มากเกินไป คำแนะนำเบื้องต้นของฉันคือ Fortran แต่ PI สนใจเราที่เปลี่ยนเป็น R ดังนั้นเขาต้องการให้ฉันตรวจสอบ ขอบคุณ!
Melissa

7

ฉันเข้าใจว่าโดยค่าเริ่มต้น SAS สามารถทำงานกับรุ่นที่ใหญ่กว่าหน่วยความจำได้ แต่นี่ไม่ใช่กรณีของ R ยกเว้นว่าคุณใช้แพคเกจเช่น biglm หรือ ff โดยเฉพาะ

อย่างไรก็ตามถ้าคุณทำอาเรย์ทำงานในอาร์ที่สามารถเวกเตอร์ได้มันจะเร็วมาก - บางทีความเร็วครึ่งหนึ่งของโปรแกรม C ในบางกรณี แต่ถ้าคุณทำบางอย่างที่ไม่สามารถเวกเตอร์ได้มันจะดูค่อนข้างมาก ช้า. เพื่อให้ตัวอย่าง:

# 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

เมื่อฉันเพิ่ม N เป็นสิบถึง 100,000 ฉันจะยกเลิกการทดสอบ 4 หลังจาก 20 นาที แต่การทดสอบ 1: 3 ใช้เวลา 61, 3 และ 37 มิลลิวินาทีต่อวินาที

สำหรับ N = 10,000,000 เวลาสำหรับการทดสอบ 1: 3 คือ 3.3s, 0.6s และ 1.6s

โปรดทราบว่าสิ่งนี้ทำบนแล็ปท็อป i7 และที่ 480mb สำหรับ N = 10million หน่วยความจำไม่ใช่ปัญหา

สำหรับผู้ใช้บน Windows 32 บิตจะมีขีด จำกัด หน่วยความจำ 1.5GB สำหรับ R ไม่ว่าคุณจะมีหน่วยความจำเท่าใด แต่ไม่มีขีด จำกัด ดังกล่าวสำหรับ Windows 64 บิตหรือ Linux 64 บิต หน่วยความจำวันนี้ราคาถูกมากเมื่อเทียบกับราคาชั่วโมงของฉันดังนั้นฉันเพิ่งซื้อหน่วยความจำมากกว่าใช้เวลาพยายามที่จะได้รับรอบนี้ แต่นี่ถือว่ารุ่นของคุณพอดีกับหน่วยความจำ


1
(+1) ขอขอบคุณที่เสนอภาพประกอบที่มีประโยชน์ Sean!
whuber

3

(2) ตามหลักแล้วเราต้องการสร้างไฟล์เรียกทำงาน แต่ปกติแล้ว R จะใช้เป็นภาษาสคริปต์

ใช่และนี่คือเหตุผลที่ดีที่ย้ายไปยัง R ความสนใจในการเขียนแพ็กเกจ R คือการอนุญาตให้ผู้ใช้ทำให้ฟังก์ชั่นของคุณโต้ตอบกับเครื่องมืออื่น ๆ ที่จัดหาโดย R ได้อย่างง่ายดายเช่นป้อนข้อมูล bootstraped ... หากคุณไม่คิดว่านี่เป็นสิ่งสำคัญให้ใช้ภาษา C / C ++ หรือภาษาที่คุณโปรดปราน

O()rle()มันจะรวดเร็ว (เป็นการคอมไพล์ล่วงหน้า ฟังก์ชั่น) หากคุณสคริปต์อัลกอริทึมเดียวกันทั้งหมดมันจะช้า (มันจะถูกตีความ) นี่เป็นตัวอย่างพื้นฐาน: คุณมีลูกเล่นมากมายที่ใช้เวกเตอร์และเมทริกซ์เพื่อหลีกเลี่ยงการตีความลูปและทำให้ฟังก์ชั่น precompiled ทำหน้าที่ได้ทั้งหมด

ดังนั้นจงระวังให้มาก หลังจากที่คุณลองครั้งแรกคุณจะรู้สึกรังเกียจด้วย R เพราะคุณจะพบว่ามันช้าพร้อมกับรูปแบบแปลก ๆ ฯลฯ เมื่อคุณรู้ว่ามันเป็นเครื่องมือที่มีประสิทธิภาพมาก คุณอาจสิ้นสุดโดยการเขียนสคริปต์วิธีการของคุณใน R เป็นขั้นตอนเบื้องต้นสำหรับการเข้ารหัส C / C ++ ขั้นตอนสุดท้ายคือการเรียนรู้ API ของ R เพื่อสร้างฟังก์ชั่นที่เตรียมไว้ล่วงหน้าและคุณจะเป็นตัวช่วยสร้าง R :)


2

การจัดการอาร์เรย์ในหน่วยความจำเป็นเรื่องใหญ่สำหรับ SAS ฉันไม่ทราบรายละเอียดเฉพาะเกี่ยวกับ R แต่ฉันคาดการณ์ว่า R จะทำงานในหน่วยความจำโดยค่าเริ่มต้นเนื่องจากแพ็คเกจการขยายหน่วยความจำสำหรับ R, ff และ bigmemory ย้ายข้อมูลจากหน่วยความจำไปยังดิสก์ ฉันมีตัวชี้สำหรับคุณถ้าคุณต้องการปรับปรุงความเร็วหรือการใช้หน่วยความจำ ในการเพิ่มความเร็วคุณต้องใช้ R ตามที่ต้องการนั่นคือ: vectorize รหัสของคุณและใช้การรวบรวมรหัสไบต์ (เช่น: หลีกเลี่ยงการดำเนินการคัดลอกหน่วยความจำให้มากที่สุด) ประการที่สองใช้โค้ดตัวสร้างโปรไฟล์ Rprof () เพื่อระบุแพตช์ช้าในรหัสของคุณและเขียนใหม่ใน C หรือ C ++ หากจำเป็น หากคุณต้องการหน่วยความจำเพิ่มเติมคุณสามารถใช้อาร์กิวเมนต์ skip ในฟังก์ชั่น read.table () เพื่ออ่านข้อมูลของคุณทีละชิ้นและคุณยังสามารถใช้แพคเกจเช่น RMySQL ซึ่งเพิ่มยูทิลิตี้การจัดการฐานข้อมูลให้กับอาร์ หากคุณต้องการหน่วยความจำมากกว่าเดิมและสามารถลดความเร็วไปพร้อม ๆ กันคุณสามารถใช้แพ็คเกจหิมะเพื่อเรียกใช้ R แบบขนาน (คุณสามารถหารายละเอียดเกี่ยวกับเรื่องนี้และอื่น ๆ อีกมากมายในหนังสือ "The Art of R Programming" โดย Norman Matloff จัดพิมพ์เมื่อปลายปีที่แล้วรายละเอียดเกี่ยวกับแพ็คเกจที่กล่าวถึงนี้สามารถพบได้ทางออนไลน์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.