• mac 别用 gcc, 把 gcc 卸掉

  • 进程死锁 at 2018年06月08日

    JRuby 的线程不太一样,好久没用过了

  • Squirrel 输入法可以设定,切换到哪个程序时就自动转英文输入状态

  • Vue 今年 Star 大概会超过 React ... 优势是 Vue 还支持 Pug / Sass 这些语法,hot reload 保存见效果. 劣势是如果得后端渲染要么写两份,要么用耗内存巨多的方法载一个 node 环境去渲染。API 调用太多效率也会超级低。

    如果还想发挥 Rails 的优势,那么明显就是用 Turbolinks + Stimulus 而不是 Vue 这些啊。

  • 可能是找不到 libxml2 或者 libxslt

    你看看 ls /usr/include/libxslt 有没有,如果没有那就

    brew install libxml2 libxslt
    gem install nokogiri -v '1.8.2' -- --with-xslt-dir=/usr/local/opt/libxslt --with-xml2-dir=/usr/local/opt/libxml2
    

    然后 bundle

  • 挺简洁清晰的,不用改

  • 后台管理为啥要兼容各种浏览器?需要设计的东西用框架就不好实现,最终还得自己写一套

  • 因为静态文件在 production 下不通过 Rails 服务。你得配置你的 web server (apache? nginx?) 而不是 Rack middleware

  • 其实自己写 css 就好了,不需要像组件库那样考虑那么多乱七八糟的情况和用例,实际全套不会超过 1000 行. 复杂点的组件样式和效果去 codepen 抄,比它们的好看

  • U 盘插其它电脑试试是否 U 盘坏了 换个口试试是否 U 口坏了

    再不行就重置 SMC 试试:https://support.apple.com/zh-cn/HT201295 再不行就重置 PRAM 试试:https://support.apple.com/zh-cn/HT204063

  • 不推荐在 Ruby 用这些东西,会让你的代码变得低效而多 bug

  • 为啥不用内置的... 就是为了把简单问题复杂化?

  • 你要的一行版

    Hash.new(0).tap{|h| arr.each{|(k,v)| h[k] += v.to_i } }
    
  • h = Hash.new 0
    arr.each {|(k,v)| h[k] += v.to_i }
    
  • 1.upto(a.size).map{|i| a.take(i).join '/' }
    
  • MySQL 或者 PG 到 PB 级别都没问题的啊,无非就是集群而已

    然后搭配一个时序性的就好,例如 ClickHouse 了解一下

  • 不杠就没啥好说了...

  • 不是必须的,只是 webpacker 把它们都用上了而已。

    webpack 的配置很复杂,配置它的 file-loader / url-loader 也可以。但感觉你也不想花功夫了解,所以还是建议拷进来...

  • 和 yarn 没关系,和你用的包,和你打包工具 (webpack?) 的 resolve 方式有关系。

    如果你用的包很久没更新过了,估计它对现在的打包工具没什么概念 (例如 simple-line-icons), 你就直接拷过来好了。

  • select2 有点大啊... 其实用 bootstrap 那样的 dropdown 就可以了

  • 挺好的,但是软件支持不好。

    macOS 的双拼增加了 sougou 键位(以前的微软拼音双拼键位)就回来用了一下

    感觉已经不错了,比默认的键位好。但是 mac 的拼音翻页键不能自定义,不如鼠须管双拼定制性强。

    虽然鼠须管对简体支持实在不怎么样,而且词典不太行……

  • node 不适合 docker, node_modules 这么多,在 Mac / Windows 会非常慢...

  • 前排

  • File.write 'test1.txt', "标题信息:#{@task.title}", encoding: 'gbk'

  • 楼主的应用性能算不错了,但当性能优化到一定程度时,这些追踪的代码就很可能会成为比较大的影响因素了

    1. 本机通信例如应用服务器和 Nginx 之间都用 Unix Domain Socket 而不用端口,负载均衡/应用服务器/数据库都开启 BBR 和 TCP fast open

    2. 看看火焰图找瓶颈

    • 基于 ruby-prof 的:ruby-prof-flamegraph , 但是 ruby-prof 需要 require 进去,本身会影响性能。但是结果基本会反映各方法的 CPU 占用率,容易找出计算密集的方法
    • rbtrace 类似 strace, 不用 require 就能 sample 请求,对真机性能基本无影响,采样结果反映各方法的栈顶耗时,容易找出网络 IO 耗时长的方法

    \3. 升级 Ruby 或者修改编译参数,会有一些性能改进

    \4. 日志采集/sentry/newrelic 也很耗性能... 看看线程数有没有大超标

    ActiveModelSerializer 或者 jbuilder 的设计都比较臃肿,都是消耗 CPU 比较大的库,可以换个快一点的。

    把不要的 Rack 中间件都去掉,例如基于 token 的 API 请求就不需要 session 了

  • JIT for MRI 开始开发了 at 2018年03月04日

    但 GCC 的 RTL 和 Markorov 的 RTL 确切来说不是同一套东西,虽然都属于寄存器机指令...

    现在 Ruby 的字节码指令比较接近栈机指令,栈机指令特征是很多操作数都是栈上 implicit 的,总长度可以比较短。典型的栈机指令是类似这样的:

    push a
    push b
    add # 在栈上 pop 两个元素, 相加, 然后压回栈上
    

    而寄存器机指令,其中的寄存器也不是指 CPU 里的寄存器,直接理解为局部变量好了。典型的寄存器机指令是类似这样的:

    c = add a, b
    

    其中 a, b, c 都是代表局部变量位置的整数。

    稍微跑题一下:寄存器机指令的好处是总指令数会变少,但指令编码后会比栈机指令长 (例如 JVM bytecode 编译到 Dalvik bytecode 占空间会变多 30% 左右). 就用上面两个例子来说,如果用 1 个字节代表 opcode, 那最终编码出来占用空间就是 3 + sizeof(a) + sizeof(b) 字节,而寄存器机指令编码后占用空间是 1 + sizeof(a) + sizeof(b) + sizeof(c) 字节,sizeof(c) 往往是占空间大于 2 字节的,不然就得受诸如局部变量不能超过 512 个之类的限制...

    但 YARV 和 JVM 字节码不太一样的地方是,因为 YARV 的指令是 Direct threading 的,也就是说 opcode 已经用内存地址替换了。直接放内存地址可以提高分支预测的命中,从而提高执行速度。

    再稍微跑题一下:也有人说 direct threading 是 folk lore, 以现在 CPU 强大的分支预测和推测执行,用 call threaded 也相差无几。当然推测执行的副作用不加清理的话,也会带来类似 spectre 的 bug...

    回题:内存地址本身占空间巨大,本来一字节或者不到一字节能表示的 opcode 在 64 位平台就变成了 8 字节,所以 Ruby 用栈机的空间优势其实不大... 所以替换成寄存器字节码的空间损失并不大,甚至能省一些内存。而从寄存器代码生成 JIT 的 C 代码比栈机代码更直接一些,也更容易让 C 编译器优化一些。

    现在是逐步增强的方式,先上 mjit, 再上 YARV 转译的 RTL mjit (这时就是 源代码 -> YARV 字节码 -> RTL 中间表示 -> C 代码 -> 编译成动态链接库 -> 载入 的复杂流程...).

    未来会不会把 YARV 替换掉,或者把 C 换成别的中间表示来缩短这个 JIT 的流程,就再说咯。

  • Stimulus 框架简介 at 2018年03月02日

    积少成多,水滴石穿... 顺便还可以做一下编译期检查

  • Stimulus 框架简介 at 2018年03月02日

    利用 turbolinks 和 stimulus, 再改改 slim, 就和 vue + pug 差不多了...

    简化的 slim 模板:

    / hello.slim
    div @controller="hello"
      input type="text" @target="hello.name"
      button @click="hello#greet" Greet
      span @target="hello.output"
    

    目标是让它生成 stimulus 对应的 HTML:

    <div data-controller="hello">
      <input data-target="hello.name" type="text" />
      <button data-action="click->hello#greet">Greet</button>
      <span data-target="hello.output"></span>
    </div>
    

    魔改的 slim 和测试:

    require 'slim'
    
    module Slim
      class Parser
        def parse_attributes(attributes)
          # Check to see if there is a delimiter right after the tag name
          delimiter = nil
          if @line =~ @attr_list_delims_re
            delimiter = @attr_list_delims[$1]
            @line = $'
          end
    
          if delimiter
            boolean_attr_re = /#{@attr_name}(?=(\s|#{Regexp.escape delimiter}|\Z))/
            end_re = /\A\s*#{Regexp.escape delimiter}/
          end
    
          while true
            case @line
            when @splat_attrs_regexp
              # Splat attribute
              @line = $'
              attributes << [:slim, :splat, parse_ruby_code(delimiter)]
    
            when /\A\s*@(\w+)\s*=\s*(["'])([\w\.\-\>\#]+)\2/
              attr_value = $3
              if attr_value['#']
                @line = $'
                attr_value = "#$1->#{attr_value}"
                attributes << [:html, :attr, 'data-action', [:slim, :interpolate, attr_value]]
              else
                case $1
                when 'controller'
                  @line = $'
                  attributes << [:html, :attr, 'data-controller', [:slim, :interpolate, attr_value]]
                when 'target'
                  @line = $'
                  attributes << [:html, :attr, 'data-target', [:slim, :interpolate, attr_value]]
                else
                  syntax_error!('Must use "@controller=" or "@target=" or assign "controller#action"')
                end
              end
    
            when /\A\s*@/
              syntax_error!('Expect @controller or @target or event names')
    
            when @quoted_attr_re
              # Value is quoted (static)
              @line = $'
              attributes << [:html, :attr, $1,
                             [:escape, $2.empty?, [:slim, :interpolate, parse_quoted_attribute($3)]]]
            when @code_attr_re
              # Value is ruby code
              @line = $'
              name = $1
              escape = $2.empty?
              value = parse_ruby_code(delimiter)
              syntax_error!('Invalid empty attribute') if value.empty?
              attributes << [:html, :attr, name, [:slim, :attrvalue, escape, value]]
    
            else
              break unless delimiter
    
              case @line
              when boolean_attr_re
                # Boolean attribute
                @line = $'
                attributes << [:html, :attr, $1, [:multi]]
              when end_re
                # Find ending delimiter
                @line = $'
                break
              else
                # Found something where an attribute should be
                @line.lstrip!
                syntax_error!('Expected attribute') unless @line.empty?
    
                # Attributes span multiple lines
                @stacks.last << [:newline]
                syntax_error!("Expected closing delimiter #{delimiter}") if @lines.empty?
                next_line
              end
            end
          end
        end
      end
    end
    
    result = Slim::Template.new('hello.slim').render binding
    
    puts result