• 小学教的九九乘法表和应用题一点用都没有,早点教代数和方程才是正道...

  • fn + 左 = home

  • 苹果鼠标用什么鼠标垫好 at 2013年03月07日

    可以试试游戏专用的鼠标垫,各种微晶涂层什么的

  • 满屏幕的这种错误 何解? at 2013年03月06日

    载入了两次

  • #9 楼 @zhulinpinyu 因为暴雪的服务器周二维护 ...

  • MatchData 问题 at 2013年03月04日
  • #6 楼 @iBachue ... 早升级避免技术债利滚利...

  • nginx 的 400 错误 at 2013年03月04日

    localhost 的 cookie 是否太大了?

  • MatchData 问题 at 2013年03月04日

    因为 2.0 的 rdoc 可以指定除了 obj 以外的某些参数/返回类型了... 所以就能表达出更详细的 str or nil...

  • #4 楼 @iBachue 1.9.3p374 和 2.0-p0 都可以啊

  • #2 楼 @iBachue

    其实只有 .net 的正则支持字符组减法:[\w-[_]]

    不过实现字符组减法还有一招叫做 double negate: [^_[^\w\d\?\-\'\.\,\/@&\(\)]]

  • /(?!_)[\w\d\?\-\'\.\,\/@&\(\)]/

  • #8 楼 @saillee 只能一步步看区别是什么了...

    对比 public key: 如果 C# 可以把 public key 用 pem 的格式输出,在 ruby 中也输出一个 pem (pub_key.to_pem), 可以对比一下是否一样...

    对比加密前的消息: 在 C# 中把 bytes 打出来,在 ruby 中把message_string.encode('UTF-16LE').unpack('c*') 打出来,对比一样是否也一样...

  • #3 楼 @saillee

    no need to unpack

    ...
      m = Base64.decode64(d.find_first('Modulus').content)
      e = Base64.decode64(d.find_first('Exponent').content)
    
      pub_key = OpenSSL::PKey::RSA.new
      # modulus
      pub_key.n = OpenSSL::BN.new m, 2
      # exponent
      pub_key.e = OpenSSL::BN.new e, 2
    ...
    
  • 你那个 publickey 不像 xml 啊

  • #11 楼 @hlxwell 前缀运算符只有 +, -, ~

    鱼骨运算符 >-+->, 飞碟运算符 <-+->, 射箭运算符 >>-->:

    class Proc
      def -@; self; end
      def +@; self; end
    end
    
    Cat = Struct.new :fish
    class Cat
      def > p; self.fish += p[]; end
      def < p; self.fish -= p[]; end
      def >> p; self.fish = p[]; end
    end
    
    Cat[1]  >-+->  {0_0}
    Cat[1]  <-+->  {0_0}
    Cat[1]  >>-->  {0_0}
    
  • #53 楼 @bhuztez C++ 可以预先生成两个函数,然后按情况在虚函数表中替代掉,不用写内存页的...

    | 而编译器或者 JIT,知道 x 和 y 的值,就可以直接把 x 和 y 当作常量代入,于是这个表达式就被优化掉了

    你说的这个是常量折叠而不是常量内联... 在 ruby 里 1 + 2 的结果可以不是 3 的... 到头来还要做退优化

    tracing jit 被吹得太过头了... 我只是觉得在正则引擎 onigmo 里做 jit 更实在点...

  • #51 楼 @bhuztez offline 编译器不用考虑编译时间,可以做复杂很高的代价比较,找到最佳的生成结果。vm 对 offline 编译器的唯一优势是按照运行情况去动态修改代码,但现在的 C 编译器各种黑魔法,已经具备一些运行时修改代码的能力了... 例如用 C++ 实现 singleton, getInstance() 这么写的话:

    class Klass {
      static Klass* instance = NULL;
      public:
      static Klass* getInstance() {
        if (!instance) {
          instance = new Klass();
        }
        return instance;
      }
      ...
    }
    

    其中的 if 条件判断在多次运行之后可以被省略掉,不判断就直接返回 instance 了。


    ruby vm 已经有常量代入的能力了,和 jit 无关,叫做 inline const cache. 实现方法是第一次调用这个常量的时候就在 byte code 中嵌入常量的值。如果发生了常量重新定义,vm 里维持的一个版本字段会更新,然后所有的 const cache 都会失效。


    把 bytecode 指令的实现作为模板写出来的 jit 几乎没有速度改进的... 这样的 jit 比 direct threading 只少了 goto *ip++; 产生的几条指令,但是用了 operand predecode 手段的话,可以利用 CPU 的乱序执行能力在很少的时钟周期内完成执行完很多指令。真正有效果的 jit 要么需要手写很多汇编代码,要么重新做寄存器分配,没有 super instruction 那么好实现,而且 super instruction 可以利用 offline 编译器的优化能力,可移植性也更好...


    分支预测有很多种,最简单的是预测 goto label. 某些 CPU 可以还能根据段寄存器或者指令寄存器 RIP 指向的地址去扫描代码找跳转,所以有 context threading 的优化方法:某些情况下把 vm 里虚拟的 instruction pointer 放到指令寄存器中去。至于 "90% 的分支预测命中率" 之类的看不到上下文没什么意义吧...


    做 jit 有很多方法... rubinius 是基于 llvm bytecode 做 jit 的,但由于多了一个 llvm 字节码中间层,编译的消耗也多大,ytljit 是基于 yarv bytecode 的 jit. 我觉得 tracing jit 更适合 v8 那种一开始就放弃 bytecode 的 vm ...

  • 或者

    puts 'website:
     www.dousile.com'
    
  • #34 楼 @skandhas

    jit 编译就是用空间换时间... 解释器的优势是操作的抽象度高,可执行代码可以挤到很小的内存中去,mruby 用 jit 的话也就只能适用于很小的一部分移动设备...

    另外解释器也能到达很高的速度的,luajit2 的解释模式就比 luajit1 的 jit 模式快。1.8 时代有个 AOT (ahead of time) 编译器 ruby2cext, 把 ruby 翻译成 C, 然后让 C 编译器用最大优化度去编译,可以提升不少速度,但是这个方法对 1.9 已经没有改进的效果了... 一个 jit 的优化能力一般是比不上 C 编译器的...

    完成日常任务如 rake 或者爬虫的话,解释模式执行基本都是比 jit 快,因为很多代码都是只跑一遍,先编译成机器码再跑反而慢了。jit 对多次调用的一些 "热" 方法效果明显,但是 ruby 中比较 "热" 的很多方法已经是 C 实现的了。如果采用 jit, 可能需要把很多实现改回 ruby 才能保证速度 (就像 rubinius 里把很多很多核心方法都用 ruby 重新实现了一遍...). 有些代码多而且"热度均匀"的 java 应用为了尽可能多的 jit, 把 permanent generation 调得非常大 (好几 G 之类的), 提升效果也不明显,因为可执行机器码多了 page miss 的情况也会很严重...

    内存也是考虑因素之一。jit 后消耗内存明显增多,现在 ruby 的字节码是按照平台长度对齐的,其实是 "qword code", 吃内存已经不小了... 如果采用 jit, 可能要重新设计字节码,使用更节省内存的表示方式?但是节省内存的字节码表示方式往往不能对齐,不能对齐就会影响解释执行的速度,并且使一些技巧如 inline method caching 更难实现...

    大量运用了元编程和反射的代码,运行的时候 jit 也要多次重新编译...

    有了 jit 之后还需要做很多工作去优化,例如 java 的 jit 就能扫描一些短的方法并且把它 inline 过来,减少 method call 的时间损耗。但是一些优化手段随着 CPU 的发展没有效果甚至是反效果了,像分支预测能力比较强的 CPU, 一些方法调用的损耗几乎可以忽略,inline 进来反而增加了代码的大小,没达到提速的效果... 所以现在的最新的编译器 gcc 和 vc 都是用 profile based 的手段去检测一些指令或者代码的代价,然后按照代价选择生成最佳的机器代码。但是一个 jit 要做到这种程度代价也很高的...

    http://nominolo.blogspot.jp/2012/07/implementing-fast-interpreters.html

    虽然实现一个有效果的 jit 很困难,但 ruby 和 mruby 的 x86 jit 也是有人在做的

    再另外,速度优化不是一个 jit 能搞定的事情,gc, method dispatch 都还有优化的空间,而且现在解释器也还没有达到最优化:ruby 2.0 stack caching 的优化开关还没打开 (有些测试还跑不过去,而且没有完全的速度提升), context threading, super instruction, manual branch prediction 之类的优化技巧也还没应用上。我觉得 ruby 离 jit 还是挺远的路要走的,或者解释器上有进一步突破,干脆就不需要 jit 了,又或者发展出一个混合解释和 jit 执行的模式 (inline instruction) 也说不定...

  • #1 楼 @lgn21st

    • 考虑 % 的自定义语义不?例如让用户可以自己定义 %sql{ select * from users; } 之类的...
  • #3 楼 @windwiny fiddle 就是 ffi 啊,不过 ffi 在 cruby 和 jruby 里处理的区别很大

  • @hlxwell

    class Proc
      def -@ 
        self
      end
    end
    
    ------------------> { `o_o` }
    
  • #77 楼 @darkbaby123

    手动装 rubygems 2.0 就可以了

  • #5 楼 @lgn21st 4 核自然是 *4 最快了,*16 的话得花很多时间在线程间的 context switch

  • require "dl" 的地方改成 require 'fiddle' 呗 libffi 的包装

  • 小心身体,少熬夜别太累 at 2013年02月24日

    样子像不像星际虫族的建筑刚起来时候的泡泡?不管多大多涨都千万不要弄破...

  • 小心身体,少熬夜别太累 at 2013年02月24日

    潜伏在脊椎的水痘病毒顺着神经跑到皮肤上了,不会传染给大人,但是小朋友碰到就会得水痘