• 刚开始看的是 ruby-lang ,觉得 Ruby 语法糖很多,看完 Metaprogramming Ruby 之后发现其实核心的东西就是几点:

    1. lexical scope 和 dynamic scope
    2. block 和 proc
    3. send 和 ancestors
    4. eval

    然后也明白了很多 API 为什么要做成这个样子,写出来的代码也会喷火了

    在看 Metaprogramming Ruby 之前看过一点 Ruby Under a Microscope,主要看的是 Ruby 解释器内部机制的部分,对后来写 C Extension 也比较有帮助

  • 我入门看的 Metaprogramming Ruby,非常好

  • 快换用 Linux 吧,Linux 上开 docker 就不用了隔着虚拟机了

  • 换用 docker 开发吧

  • 主力在用非常旧的台式机,Dell T7610,七八年前生产的了

    插了两块 Intel Xeon 2680v2,20C/40T, Ivy Bridge 架构的,连 AVX2 都没有,不过 Intel 挤了这么多年牙膏,老架构也不是不能用

    插了 8 条 8G 的 DDR3 REG ECC 内存,垃圾跟不要钱一样。装了 Windows 然后把 Hyper-V 开起来,分 32G 内存出来开一个 Debian VM 写代码用,一般都是 VSCode SSH Remote 到 VM 去,然后 Windows Management PC 用来看 Chrome

    我这套开发环境大概用了两年,写一点点 Ruby 但是没怎么写过 Rails

    出门就用笔记本打 VPN 回去,继续用 VM 写代码

  • valgrind 里面的 massif 工具 trace heap

    然后使用 massif-visualizer 进行可视化

  • 🐂🍺

  • 想自己找原因的话给几个建议

    1. 编译一个 -Og 的 ruby
    2. 把 valgrind 和 gdb 挂上去看看
  • extconf.rb

    require 'mkmf'
    $CFLAGS << ' -O3 '
    $CFLAGS << ' -std=c99'
    create_makefile('rotate')
    
    

    rotate.h

    #ifndef ROTATE_H
    #define ROTATE_H
    /* Nothing to expose */
    #endif
    
    

    rotate.c

    #include "rotate.h"
    #include <ruby.h>
    #include <stdint.h>
    #ifdef __x86_64__
    #ifdef __linux__
    #include <x86intrin.h>
    #endif
    #endif
    /* Support more arch/cc if you want */
    
    static VALUE rb_mRotate;
    static VALUE rb_mRotate_Native;
    static VALUE rb_mRotate_Native_U64;
    
    static VALUE rotate_native_u64_rb_left(VALUE self, VALUE src, VALUE bits);
    
    void Init_rotate(void)
    {
        rb_mRotate = rb_define_module("Rotate");
        rb_mRotate_Native = rb_define_module_under(rb_mRotate, "Native");
        rb_mRotate_Native_U64 = rb_define_module_under(rb_mRotate_Native, "U64");
        rb_define_module_function(rb_mRotate_Native_U64, "left", rotate_native_u64_rb_left, 2);
    }
    
    static VALUE rotate_native_u64_rb_left(VALUE self, VALUE src, VALUE rot)
    {
        uint64_t source = NUM2ULL(src);
        uint64_t rotate = NUM2ULL(rot);
    
        return ULL2NUM(__rolq(source, rotate));
    }
    
    

    Run ruby extconf.rb && make

    test.rb

    require_relative 'rotate'
    
    puts Rotate::Native::U64.left(1,63)
    # => 9223372036854775808
    puts Rotate::Native::U64.left(1,64)
    # => 1
    
    

  • Intel Xeon E5-2680v2, Ivy Bridge, 20C/40T

    32G DRAM

    5.10.0-3-amd64 #1 SMP Debian 5.10.12-1 (2021-01-30) x86_64 GNU/Linux

    Ruby 3.0.0

    正常运行

    require 'digest/md5'
    e = (1..1_000_000).to_a
    arr = [e,e,e,e]
    
    result = arr.map { |sub_arr|
      Ractor.new(sub_arr) do |sub_arr|
        sub_arr.map {
          Digest::MD5.hexdigest(rand.to_s)
        }
      end
    }.map{|r| r.take}.reduce(:+)
    

    heap trace