• R语言高性能编程,优化(一)


    这段时间学习了<R高性能编程>这本书,基于这段时间做的项目实践,总结了一些自己的体会,和大家分享

    一、为什么R程序有时候会很慢?
    1、计算性能的三个限制条件 cpu ram io R代码本身
    2、R是运行时解释的 在运行时解释并执行R代码
    3、R是单线程的 CPU的强大核心并没卵用,R只会只用一个
    4、R需要将全部数据加载到内存 处理的最大数据了取决于内存的限制 
    这里 linux相比于windows有一个优势,当我们试图装载一个可用内存大小的数据集
    数据可能会成功装载,不过一旦可用内存耗尽,操作系统会将内存中的数据换到磁盘(交换空间)上
    的交换文件,R人为数据全部装载入内存时间上OS正在做内存和磁盘文件的数据交换工作,如此一来,磁盘IO瓶颈对R性能就有着巨大的影响
    5、算法设计影响时间和空间复杂度
    时间复杂度:运行R程序需要的计算时间和数据规模之间的关系
    空间复杂度:运行R程序需要的内存量和数据规模之间的关系

    二、衡量代码的性能常用办法
    使用system.time() benchmark() microbenchmark() 
    Rprof() 的工作原理是在运行R表达式的时候 ,观察R的调用栈,并以固定的时间,默认是0.02秒,对调用栈进行快照
    ,从而确定函数当前正在执行什么操作。通过这些快照,summaryRprof 能够计算每个函数的耗时
    要理解R程序各个部分的性能,快速发现瓶颈,Rprof 是个很有用的工具
    内存分析 memory.profiling=TRUE 这个指标会有误导,会偏高,因为有些函数内存尚未释放,

    三、加快R运行的简单方法
    1、尽量向量化运算,避免循环
    2、使用内置函数。 R中存在很多低级运算符,虽然这些运算符可以组成更加复杂的运算符或者函数,但是和编译性语言相比性能很差,
    但是R提供了很多C++编写的计算包。
    比如计算 矩阵每一行的和,一般用apply可以解决问题,但是内置函数 rowSums,性能提升11倍,rowSums是使用C预编译的优化函数
    开源社区开发了很多函数优化库供R使用,比如 basic linear algebra subprograms (BLAS) 详见:www.netlib.org.blas
    3、预分配内存
    为什么要预分配内存呢?主要是因为动态分配内存会拖慢程序的运行速度,每当向量大小发生变化,程序都需要做一些额外的工作
    经过测试在一个简单的加法运算中,1000 长度的向量的计算,预分配内存之前为25.373秒,之后为0.577 秒
    4、使用简单的数据结构
    5、使用更加简单的数据结构
    比如 如果可以的话,尽量使用matrix 而不是 dataframe,因为大部分矩阵操作首先要把dataframe强制转换为matrix,才开始计算。
    如果数据中存在多种变量类型,不可避免的要使用dataframe的时候,尽量用subset 和 which 筛选子集后再做运算。
    6、使用哈希表进行大型数据上的频繁查找
    一个包含N个元素的列表上的查找操作的时间复杂度是O(N) 列表越靠后,查找时间越长,随着N的增加,情况越严重。
    CRAN 上可用的R 包是hash, 哈希表上查找操作的时间复杂度为O(1)
    7、去CRAN上寻找更快的包
    例如:fastcluster,princomp,fastmatch,RcppEigen,data.table,dplyr

    四、使用编译代码加快运行速度
    1、在运行之前编译R代码 因为每次运行前都需要解析和评估代码。这需要话费大量CPU时间,拖慢运行速度。
    利用compiler 包,能在一定程度上减少此问题,提前预编译。
    cmpfun 编译函数
    compile 编译表达式
    cmpfile 编译存储在文件中的R表达式
    2、即时编译 激活JIT(just in time) compiler 包的enableJIT
    3、在R中使用编译语言 在R中嵌入C、C++、OC、OC++(inline包)
    4、调用外部编译代码 Rcpp rJava 
    5、使用编译代码的注意事项
    6、创建R对象及垃圾回收
    预分配变量内存,PROTECT防止R的垃圾收集器清理对象。 UNPROTECT 解除已分配内存的保护

    五、使用GPU让R运行的更快
    这里需要注意的是在计算pearson相关性的时候,GPU是比CPU慢的
    1、GPU最大的优势是核心数量巨多,所以最适合数据的并行问题,不适合那些线程之间需要大量同步的任务。
    2、GPU的性能主要取决于主内存(RAM)和GPU内存之间的数据传输量,因为RAM和CPU内存之间的连接宽带很低。
    优秀的GPU编程应该最小化这种传输

    ----------好了,截止到这里 我们已经了解了R为什么会慢以及如何衡量R代码的性能的问题;并且突破了CPU 限制,提升R程序性能的技术。

    后面会以内存和IO方面作为突破口来优化代码,未完待续.....

    原文出处:http://www.cnblogs.com/qiaoyihang/p/7779144.html

  • 相关阅读:
    深挖 GIL锁
    numpy小入门
    IPython和Jupyter notebook
    LINUX+Vmware+SVN的配置和安装
    windows下使用火狐浏览器插件AutoProxy+MyEnTunnel+SSH访问海外站点(转)
    无法打开键: UNKNOWNComponentsBE1FB738077DBE490AF18C3B9B1A1EE8E5F5286B58B542741A00A0A9AA420B27
    如何将软件测试和数据库联系在一起(转)
    接口测试第十二课(fidller过滤)(转)
    android、IOS和手机基础知识
    广州女生手机被偷 里面的身份证出卖了支付宝密码丨丢手机后必做6件事(转)
  • 原文地址:https://www.cnblogs.com/qiaoyihang/p/7779144.html
Copyright © 2020-2023  润新知