`
dongbin
  • 浏览: 245591 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

使用Ruby实现算法时遇到的性能问题

    博客分类:
  • Ruby
阅读更多
昨天作了一道Topcoder的题目,是一道典型的图搜索问题。由于正在学习Ruby,所以用Ruby实现了一下。
 
测试时发现规模小的时候比如100*100以下的图,运行时间还可以接受。而题目要求是500*500的图,这种规模下,运行时间已经超出了我的耐心。
 
一般来说,Topcoder的题目都是能够十多秒运行出结果的,否则就是没有做对。
 
本来以为是我的算法写的有问题,所以反复检查我的算法,并没有发现更有效率的途径。
 
开始怀疑ruby的性能问题,用Java把其中的堆数据结构重新实现了一次,然后和ruby实现的堆进行比较。
 
结果让人大吃一惊,竟然比ruby快20-30倍。我的测试并不权威,所以具体数据我就不贴出来了,以免发生非议。程序在后面,有兴趣的自己测试一下。
 
用Java实现是可以满足时间要求的,所以问题是在性能上。
 
结论:世间没有药能治百病,编程语言也是如此。脚本语言有着数倍于强类型语言的编程效率,同样也有着接近一个数量级的效率低下。
 
我这个测试并不代表现实世界脚本语言应用程序的效率,因为大部分脚本应用程序属于IO密集型,比如网站,解释速度不是瓶颈。
 
在关键任务上,可以使用ruby作为粘合剂,而算法用C或者C++实现。充分利用各种语言的优势。
 
 附:堆数据结构的 ruby 和 java 实现
 

Ruby实现:

 
 
class Heap
    def initialize(list)
        @heap =[]
        insert(list)
    end
   
    def push(item)
        @heap.push(item)
        go_up(@heap.size-1)
    end
   
    def insert (list)
        list.each do |item|
            push(item)
        end
    end
   
    def pop_each
        while data = pop
            break if yield(data)
        end
    end
   
    def pop
        if  @heap.size>1
            result = @heap.first
            @heap[0] = @heap.pop;
            go_down(0)
            return result
        elsif @heap.size==1
            return @heap.pop
        else
            nil
        end
    end
   
    private
   
    def go_up(pos)
        if parent(pos) >= 0 && @heap[pos]<@heap[parent(pos)]
            swap(pos,parent(pos))
            go_up(parent(pos))
        end
    end
   
    def go_down(pos)
        tmp = min(pos)
        if tmp!=pos
            swap(pos,tmp)
            go_down(tmp)
        end
    end
   
    def min(root)
        minPos(right_child(root) ,minPos(left_child(root)  , root) )
    end
   
    def minPos (left, right)
        return left > 0 ? (@heap[left]< @heap[right] ? left : right) : right
    end
   
    def parent(pos)
        pos > 0 ? (pos-1)/2 :-1
    end
   
    def left_child(pos)
        pos*2+1 < @heap.size ? pos*2+1 : -1
    end
   
    def right_child(pos)
        pos*2 +2 < @heap.size ? pos*2+2 : -1
    end
   
    def swap(left,right)
        tmp =@heap[left]
        @heap[left]=@heap[right]
        @heap[right]=tmp
    end
   
end
 

 java实现:

 

/**
 *
 */
package test;
import java.util.ArrayList;
import java.util.List;
/**
 * @author dongbin
 *
 */
public class Heap {
 List<Comparable> heap = new ArrayList<Comparable>();
 public Heap(List<Comparable> data) {
  insert(data);
 }
 private void insert(List<Comparable> data) {
  for (Comparable object : data) {
   push(object);
  }
 }
 public void push(Comparable obj) {
  heap.add(obj);
  goUp(heap.size()-1);
 }
 
 public Object pop(){
  if(heap.size()>1){
   Object result = heap.get(0);
   heap.set(0,heap.remove(heap.size()-1));
   goDown(0);
   return result;
  }else if (heap.size()==1){
   return heap.remove(0);
  }else{
   return null;
  }
 }
 private int min(int root) {
  return minPos(right_child(root), minPos(left_child(root), root));
 }
 private int minPos(int left, int right) {
  return left > 0 ? (heap.get(left).compareTo(heap.get(right)) < 0 ? left
    : right) : right;
 }
 private void goUp(int pos) {
  if (parent(pos) >= 0
    && heap.get(pos).compareTo(heap.get(parent(pos))) < 0) {
   swap(pos,parent(pos));
   goUp(parent(pos));
  }
 }
 
 private void goDown(int pos){
  int min = min(pos);
  if(min!=pos){
   swap(pos,min);
   goDown(min);
  }
 }
 
 private void swap(int left , int right){
  heap.set(right,heap.set(left,heap.get(right)));
 }
 private int parent(int pos) {
  return pos > 0 ? (pos - 1) >> 1 : -1;
 }
 private int right_child(int pos) {
  return (pos << 1) + 2 < heap.size() ? (pos << 1) + 2 : -1;
 }
 private int left_child(int pos) {
  return (pos << 1) + 1 < heap.size() ? (pos << 1) + 1 : -1;
 }
}
分享到:
评论

相关推荐

    ruby-2.6.3源码压缩包

    同时,通过阅读源码,开发者可以深入理解Ruby的内部机制,学习如何实现一个动态语言的编译器和运行时系统。这对于想要参与Ruby核心开发或者希望提升编程技能的人来说,是一份宝贵的资源。 为了编译和运行Ruby源码,...

    24_ruby_algorithm_

    标题 "24_ruby_algorithm_" 暗示我们要讨论的是使用 Ruby 编程语言实现解决数学游戏“24点”的算法。在这个经典游戏中,玩家需要使用加法、减法、乘法和除法(以及括号)将四张扑克牌上的数字组合起来,使得结果等于...

    Ruby-rubyfann与FANNFastArtificialNeuralNetwork接口的Ruby库

    同时,它有一个活跃的社区,用户可以在遇到问题时寻求帮助。 在实际应用中,ruby-fann常用于各种机器学习场景,如图像识别、语音识别、自然语言处理等。开发者可以根据自己的需求,结合其他Ruby库(如Numo::NArray...

    SVM的Ruby源程序

    在Ruby中实现SVM,我们可能会遇到以下关键概念和技术: 1. **数据预处理**:在训练SVM之前,数据通常需要进行标准化(归一化或中心化),以确保各个特征在同一尺度上,这对优化过程至关重要。 2. **核函数**:SVM...

    Ruby中的协同过滤推荐系统实现,包括SVD和增量SVD_Ruby_下载.zip

    在大数据环境下,协同过滤的SVD实现可能会遇到计算复杂度和内存限制的问题。增量SVD则是一种优化策略,它不是一次性处理整个评分矩阵,而是分批处理新来的数据或更新。这种方法可以有效地应对数据流的变化,减少...

    Ruby Cookbook (第1版)

    5. **数据结构与算法**:这部分内容侧重于Ruby如何高效地处理数据结构和实现算法,这对于提高程序性能至关重要。 6. **并发与网络编程**:讨论了Ruby中的并发机制和网络编程技巧,这对于开发高性能的应用程序非常有...

    ruby 阳历农历转换类

    7. **异常处理**:在进行日期转换时,可能会遇到无效的输入,如非法的年份、月份或日期,因此需要添加适当的错误处理机制。 8. **性能优化**:如果转换类需要处理大量日期,那么优化算法以提高效率就显得尤为重要。...

    ruby_1_9_3_core_rdocs.gz

    Ruby 1.9.3是Ruby的一个重要版本,它在1.9系列中引入了诸多改进和新特性,进一步提升了性能和兼容性。本文将围绕"ruby_1_9_3_core_rdocs.gz"这个压缩包中的核心API,深入探讨Ruby 1.9.3的关键知识点。 1. **对象...

    Ruby 稳定版 v2.7.2

    比如,增加了更详细的堆栈跟踪信息,使得开发者在遇到错误时能更快地定位问题所在。同时,Ruby 2.7.2改进了对异常的处理,使得错误信息更加清晰明了,有助于快速解决问题。 在兼容性方面,Ruby 2.7.2致力于保持与...

    codewars_problems_ruby

    本篇文章将深入探讨在Ruby中遇到的Codewars问题及其解决策略,旨在帮助读者深化对Ruby语言的理解,并提升实际编程能力。 Ruby是一种面向对象的、动态类型的编程语言,以其简洁、优雅的语法和强大的元编程能力而闻名...

    advent-of-code-2015:Code 2015练习的到来,主要在Ruby中完成

    在解决AOC 2015的挑战时,Ruby的特性如元编程、块、闭包以及内置的哈希和数组类都能帮助开发者快速实现算法。 在这个advent-of-code-2015-master压缩包中,我们可以期待看到一系列的Ruby源代码文件,每个文件对应...

    libruby.2.0.0.dylib.zip

    本文将详细探讨`libruby.2.0.0.dylib`,这是Cycript中使用的一个关键组件,用于实现对Ruby语言的交互。 首先,`libruby`是Ruby解释器的核心库,包含了运行Ruby代码所必需的各种功能。`2.0.0`则是这个库的版本号,...

    desfio_cachipun_avanzado_ruby

    10. **性能优化**:学习如何分析和优化Ruby代码的性能,如使用Benchmark模块进行性能测试,或者了解内存管理和GC。 参与者在解决这个挑战的过程中,不仅可以深化对Ruby语言的理解,还能锻炼问题解决和项目组织能力...

    数独解算器:数独的解决方案,数独的解决方案,由Davis Putnam编写

    这种算法尝试填充空白单元格,并在遇到冲突时回溯到上一步,不断试错直至找到唯一解。 3. **约束条件检查**:在填充单元格时,需要不断检查行、列和小九宫格的约束条件,确保每个数字仅出现一次。这可以通过遍历...

    MemCached高性能分布式的内存对象缓存系统应用说明[收集].pdf

    6. 如果遇到找不到库文件的问题,可以通过`LD_DEBUG`环境变量来追踪库文件的搜索路径,并使用`ln -s`创建软链接解决。 在实际应用中,Memcached常被用作Web应用的缓存解决方案,例如配合PHP、Python、Ruby等语言的...

    leetcode_problems

    以下是使用 Ruby 解决 LeetCode 问题时可能会遇到的一些关键知识点: 1. **基础数据类型**:Ruby 支持基本的数据类型,如整数(Integer)、浮点数(Float)、字符串(String)、布尔值(TrueClass/FalseClass)以及...

    redis-4.1.4.zip

    在遇到"编译安装ruby后启动redis集群提示缺失redis"的问题时,可能是因为Redis服务未启动或者环境变量配置不正确。首先,确保Redis服务器已经成功安装并启动,然后检查Ruby环境中的Redis客户端是否已正确安装,并且...

    Jquery AutoComplete firefox 中文 Ajax (option url or data) Jquery rails 自动完成

    在Firefox浏览器中使用jQuery AutoComplete,可能会遇到一些特定的问题,因为不同的浏览器对某些JavaScript特性可能有不同的实现或支持。这篇博客(链接已提供)可能详细讨论了在Firefox中实现jQuery AutoComplete时...

    模拟赛车笔记:布莱斯的模拟赛车笔记

    在编写和运行Ruby脚本时,遇到问题是很常见的。理解如何有效地调试代码、定位错误并修复它们,对于提升模拟赛车项目的稳定性和性能至关重要。 总之,“模拟赛车笔记:布莱斯的模拟赛车笔记”提供了使用Ruby在模拟...

Global site tag (gtag.js) - Google Analytics