mac 别用 gcc, 把 gcc 卸掉
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'
楼主的应用性能算不错了,但当性能优化到一定程度时,这些追踪的代码就很可能会成为比较大的影响因素了
本机通信例如应用服务器和 Nginx 之间都用 Unix Domain Socket 而不用端口,负载均衡/应用服务器/数据库都开启 BBR 和 TCP fast open
看看火焰图找瓶颈
\3. 升级 Ruby 或者修改编译参数,会有一些性能改进
\4. 日志采集/sentry/newrelic 也很耗性能... 看看线程数有没有大超标
ActiveModelSerializer 或者 jbuilder 的设计都比较臃肿,都是消耗 CPU 比较大的库,可以换个快一点的。
把不要的 Rack 中间件都去掉,例如基于 token 的 API 请求就不需要 session 了
但 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 的流程,就再说咯。
积少成多,水滴石穿... 顺便还可以做一下编译期检查
利用 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