我面临以下问题:我需要很多大矩阵的子集。实际上我只需要视图作为另一个函数f()的输入,所以我不需要更改值。然而,似乎R对于这项任务非常缓慢,或者我做错了什么(似乎更有可能)。玩具示例说明了选择列所需的时间,然后在另一个函数中使用它们(在这个玩具示例中,原始函数sum())。作为“基准”,我还测试了计算时间,而不是总计整个矩阵,这显然更快。我也尝试了包ref,但无法获得任何性能提升。 所以关键问题是如何在不复制矩阵的情况下对矩阵进行子集化?我感谢任何帮助,谢谢!
library(microbenchmark)
library(ref)
m0 <- matrix(rnorm(10^6), 10^3, 10^3)
r0 <- refdata(m0)
microbenchmark(m0[, 1:900], sum(m0[, 1:900]), sum(r0[,1:900]), sum(m0))
Unit: milliseconds expr min lq mean median uq m0[, 1:900] 10.087403 12.350751 16.697078 18.307475 19.054157 sum(m0[, 1:900]) 11.067583 13.341860 17.286514 19.123748 19.990661 sum(r0[, 1:900]) 11.066164 13.194244 16.869551 19.204434 20.004034 sum(m0) 1.015247 1.040574 1.059872 1.049513 1.067142 max neval 58.238217 100 25.664729 100 23.505308 100 1.233617 100
对整个矩阵求和的基准任务需要1.059872毫秒,比其他函数快16倍。
答案 0 :(得分:4)
您的解决方案的问题是子集正在分配另一个矩阵,这需要时间。
您有两种解决方案:
如果在整个矩阵上使用sum
所花费的时间对你没用,你可以在整个矩阵上使用colSums
并对结果进行分组:
sum(colSums(m0)[1:900])
或者您可以使用Rcpp计算带有子集的sum
而无需复制矩阵。
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double sumSub(const NumericMatrix& x,
const IntegerVector& colInd) {
double sum = 0;
for (IntegerVector::const_iterator it = colInd.begin(); it != colInd.end(); ++it) {
int j = *it - 1;
for (int i = 0; i < x.nrow(); i++) {
sum += x(i, j);
}
}
return sum;
}
microbenchmark(m0[, 1:900], sum(m0[, 1:900]), sum(r0[,1:900]), sum(m0),
sum(colSums(m0)[1:900]),
sumSub(m0, 1:900))
Unit: milliseconds
expr min lq mean median uq max neval
m0[, 1:900] 4.831616 5.447749 5.641096 5.675774 5.861052 6.418266 100
sum(m0[, 1:900]) 6.103985 6.475921 7.052001 6.723035 6.999226 37.085345 100
sum(r0[, 1:900]) 6.224850 6.449210 6.728681 6.705366 6.943689 7.565842 100
sum(m0) 1.110073 1.145906 1.175224 1.168696 1.197889 1.269589 100
sum(colSums(m0)[1:900]) 1.113834 1.141411 1.178913 1.168312 1.201827 1.408785 100
sumSub(m0, 1:900) 1.337188 1.368383 1.404744 1.390846 1.415434 2.459361 100
您可以使用unrolling optimization进一步优化Rcpp版本。
答案 1 :(得分:0)
使用import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Test {
public static WebDriver driver;
public static void main(String[] args) throws InterruptedException
{
System.setProperty("webdriver.chrome.driver","Resources/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.netmeds.com");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.findElement(By.xpath("//button[@title='Upload Prescription']")).click();
for(int i=1;i<5;i++)
{
driver.findElement(By.xpath("//input[@id='FileUpload"+i+"']")).sendKeys("C:\\LICENCE.jpg");
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOf(driver.findElement(By.id("loaderContainer"))));
System.out.println("File Upload "+ i + "Done");
}
}
}
我写了一个函数,其结果大约是其他方法的2倍(8倍于compiler
而不是16x):
sum(m0)
require(compiler) compiler_sum <- cmpfun({function(x) { tmp <- 0 for (i in 1:900) tmp <- tmp+sum(x[,i]) tmp }}) microbenchmark( sum(m0), compiler_sum(m0) )