加快Julia编写不佳的R示例的速度 [英] Speeding up Julia's poorly written R examples

查看:58
本文介绍了加快Julia编写不佳的R示例的速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Julia示例,用于比较R与似乎特别复杂. https://github.com/JuliaLang/julia/blob/master /test/perf/perf.R

The Julia examples to compare performance against R seem particularly convoluted. https://github.com/JuliaLang/julia/blob/master/test/perf/perf.R

您可以从以下两种算法中获得最快的性能(最好是对所做的更改进行说明,以使其更像R)?

What is the fastest performance you can eke out of the two algorithms below (preferably with an explanation of what you changed to make it more R-like)?

## mandel

mandel = function(z) {
    c = z
    maxiter = 80
    for (n in 1:maxiter) {
        if (Mod(z) > 2) return(n-1)
        z = z^2+c
    }
    return(maxiter)
}

mandelperf = function() {
    re = seq(-2,0.5,.1)
    im = seq(-1,1,.1)
    M = matrix(0.0,nrow=length(re),ncol=length(im))
    count = 1
    for (r in re) {
        for (i in im) {
            M[count] = mandel(complex(real=r,imag=i))
            count = count + 1
        }
    }
    return(M)
}

assert(sum(mandelperf()) == 14791)

## quicksort ##

qsort_kernel = function(a, lo, hi) {
    i = lo
    j = hi
    while (i < hi) {
        pivot = a[floor((lo+hi)/2)]
        while (i <= j) {
            while (a[i] < pivot) i = i + 1
            while (a[j] > pivot) j = j - 1
            if (i <= j) {
                t = a[i]
                a[i] = a[j]
                a[j] = t
            }
            i = i + 1;
            j = j - 1;
        }
        if (lo < j) qsort_kernel(a, lo, j)
        lo = i
        j = hi
    }
    return(a)
}

qsort = function(a) {
  return(qsort_kernel(a, 1, length(a)))
}

sortperf = function(n) {
    v = runif(n)
    return(qsort(v))
}

sortperf(5000)

推荐答案

嗯,在Mandelbrot的例子中,矩阵M的维度已转置

Hmm, in the Mandelbrot example the matrix M has its dimensions transposed

M = matrix(0.0,nrow=length(im), ncol=length(re))

因为它是通过在内循环中递增count(im的连续值)来填充的.我的实现在mandelperf.1中创建了一个复数向量,并对所有元素进行操作,使用索引和子集来跟踪向量中哪些元素尚未满足条件Mod(z) <= 2

because it's filled by incrementing count in the inner loop (successive values of im). My implementation creates a vector of complex numbers in mandelperf.1 and operates on all elements, using an index and subsetting to keep track of which elements of the vector have not yet satisfied the condition Mod(z) <= 2

mandel.1 = function(z, maxiter=80L) {
    c <- z
    result <- integer(length(z))
    i <- seq_along(z)
    n <- 0L
    while (n < maxiter && length(z)) {
        j <- Mod(z) <= 2
        if (!all(j)) {
            result[i[!j]] <- n
            i <- i[j]
            z <- z[j]
            c <- c[j]
        }
        z <- z^2 + c
        n <- n + 1L
    }
    result[i] <- maxiter
    result
}

mandelperf.1 = function() {
    re = seq(-2,0.5,.1)
    im = seq(-1,1,.1)
    mandel.1(complex(real=rep(re, each=length(im)),
                     imaginary=im))
}

加快13倍的速度(结果相同但不完全相同,因为原始结果返回的是数字而不是整数).

for a 13-fold speed-up (the results are equal but not identical because the original returns numeric rather than integer values).

> library(rbenchmark)
> benchmark(mandelperf(), mandelperf.1(),
+           columns=c("test", "elapsed", "relative"),
+           order="relative")
            test elapsed relative
2 mandelperf.1()   0.412  1.00000
1   mandelperf()   5.705 13.84709

> all.equal(sum(mandelperf()), sum(mandelperf.1()))
[1] TRUE

quicksort示例实际上并未进行排序

The quicksort example doesn't actually sort

> set.seed(123L); qsort(sample(5))
[1] 2 4 1 3 5

但是我主要的目的是对枢轴周围的分区进行矢量化处理

but my main speed-up was to vectorize the partition around the pivot

qsort_kernel.1 = function(a) {
    if (length(a) < 2L)
        return(a)
    pivot <- a[floor(length(a) / 2)]
    c(qsort_kernel.1(a[a < pivot]), a[a == pivot], qsort_kernel.1(a[a > pivot]))
}

qsort.1 = function(a) {
    qsort_kernel.1(a)
}

sortperf.1 = function(n) {
    v = runif(n)
    return(qsort.1(v))
}

加速7倍(与未经校正的原件相比)

for a 7-fold speedup (in comparison to the uncorrected original)

> benchmark(sortperf(5000), sortperf.1(5000),
+           columns=c("test", "elapsed", "relative"),
+           order="relative")
              test elapsed relative
2 sortperf.1(5000)    6.60 1.000000
1   sortperf(5000)   47.73 7.231818

由于在最初的比较中,对于Mandel,Julia的速度要比R快30倍,对于快速排序,Julia的速度要快500倍,因此上述实现仍然没有真正的竞争力.

Since in the original comparison Julia is about 30 times faster than R for mandel, and 500 times faster for quicksort, the implementations above are still not really competitive.

这篇关于加快Julia编写不佳的R示例的速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆