如果区分 普通关注 和 关注大 V 分别存两个 Set,这样可以省掉 求交集的一步
建议用代码块包起来
#3 楼 @prajnamas 试了一下挺好用的
viva la BACA!!!
#12 楼 @xiaoronglv 看了下时间。。。是来不了了。。。住松江略远
可以在 contoller 中用 view_context 对象来访问所有的 helper 方法
不知道极米投影仪行不行?
这不是和天面试的差不多╭(°A°`)╮
#1 楼 @jicheng1014 我也遇到这个问题,多谢
请问楼主 generate_authentication_token
中为什么要用 loop 呢?
哦,是要保证 token 的唯一性。。。
#19 楼 @vincent 我是直接本机 rake 的,没有用 dalli,ruby 2.2 + rails 4.2 数据如下:
user system total real
1 0.750000 0.050000 0.800000 ( 0.798077)
1_ 0.530000 0.060000 0.590000 ( 0.595011)
10 0.480000 0.050000 0.530000 ( 0.527158)
30 0.470000 0.040000 0.510000 ( 0.513850)
50 0.430000 0.080000 0.510000 ( 0.515523)
100 0.490000 0.050000 0.540000 ( 0.539221)
试了一下换 ruby 版本到 2.0.0 除了慢了(1 秒多),batch 依然更快
代码见 (https://gist.github.com/li-thy-um/c78ca3f5abb60d388951)
@vincent 说差异是由于 我 cache 在内存里没有用 memcached。
看 rails 源码 发现 read 比 read_muti 多了一个 修改 payload[:hit]
的操作
namespace :test do
task cache: :environment do
test_cache
# test_cache_batch
# test_read_in_batch
end
end
def read_in_batch(total, batch_size)
batch_size += 1 # 这里改了
array = []
total.times do |i|
if (i + 1) % batch_size == 0 #这里改了
Rails.cache.read_multi(*array)
array = []
else
array << "user:#{i}:counter"
end
end
end
def test_cache_batch
n = 10000
n.times {|i| Rails.cache.write "user:#{i}:counter", i * i }
Benchmark.bm do |x|
x.report " 1" do
read_in_batch n, 1
end
x.report " 10" do
read_in_batch n, 10
end
x.report " 30" do
read_in_batch n, 30
end
x.report " 50" do
read_in_batch n, 50
end
x.report "100" do
read_in_batch n, 100
end
end
end
def test_cache
n = 10000
n.times {|i| Rails.cache.write "user:#{i}:counter", i * i }
Benchmark.bm do |x|
x.report " 1" do
n.times do |i|
Rails.cache.read "user:#{i}:counter"
end
end
x.report " 10" do
read_in_batch n, 10
end
x.report " 30" do
read_in_batch n, 30
end
x.report " 50" do
read_in_batch n, 50
end
x.report "100" do
read_in_batch n, 100
end
end
end
代码修正后: test_cache:
user system total real
1 0.740000 0.100000 0.840000 ( 0.834747)
10 0.410000 0.050000 0.460000 ( 0.465745)
30 0.430000 0.060000 0.490000 ( 0.491213)
50 0.440000 0.060000 0.500000 ( 0.498691)
100 0.420000 0.070000 0.490000 ( 0.493613)
test_cache_batch:
user system total real
1 0.460000 0.050000 0.510000 ( 0.520317)
10 0.440000 0.060000 0.500000 ( 0.493935)
30 0.450000 0.040000 0.490000 ( 0.495721)
50 0.410000 0.080000 0.490000 ( 0.494678)
100 0.450000 0.060000 0.510000 ( 0.509924)
结论:
后续:
其实上面的测试还是有问题,并没有读全部的 cache
然后改了 read_in_batch
def read_in_batch(total, batch_size)
ids = (1..total).to_a
while !ids.empty?
batch = ids.pop(batch_size).map { |i| "user:#{i}:counter" }
Rails.cache.read_multi(*batch)
end
end
加了 2 和 3 两个 测试
test_cache
user system total real
1 0.770000 0.060000 0.830000 ( 0.828525)
2 0.460000 0.090000 0.550000 ( 0.551031)
3 0.470000 0.060000 0.530000 ( 0.537011)
10 0.470000 0.060000 0.530000 ( 0.533800)
30 0.450000 0.070000 0.520000 ( 0.509173)
50 0.430000 0.080000 0.510000 ( 0.509421)
100 0.450000 0.050000 0.500000 ( 0.512080)
test_cache_batch
user system total real
1 0.750000 0.110000 0.860000 ( 0.862681)
2 0.520000 0.060000 0.580000 ( 0.577206)
3 0.490000 0.060000 0.550000 ( 0.546603)
10 0.490000 0.040000 0.530000 ( 0.536715)
30 0.450000 0.070000 0.520000 ( 0.528250)
50 0.460000 0.090000 0.550000 ( 0.545573)
100 0.450000 0.070000 0.520000 ( 0.524905)
发现 只有 1 比较慢,2, 3 和其他基本稳定
跑 2w 条
test_cache
user system total real
1 1.210000 0.140000 1.350000 ( 1.354328)
2 0.980000 0.120000 1.100000 ( 1.098255)
3 0.940000 0.140000 1.080000 ( 1.078272)
10 0.920000 0.120000 1.040000 ( 1.054410)
30 0.910000 0.130000 1.040000 ( 1.036415)
50 0.900000 0.120000 1.020000 ( 1.023310)
100 0.940000 0.100000 1.040000 ( 1.049659)
test_cache_batch
user system total real
1 1.200000 0.170000 1.370000 ( 1.381987)
2 0.940000 0.160000 1.100000 ( 1.099291)
3 0.940000 0.140000 1.080000 ( 1.088021)
10 0.940000 0.110000 1.050000 ( 1.053521)
30 0.900000 0.140000 1.040000 ( 1.044466)
50 0.890000 0.130000 1.020000 ( 1.028398)
100 0.920000 0.140000 1.060000 ( 1.049393)
好像只是多了个常数
跑 4w 条
test_cache
user system total real
1 2.440000 0.310000 2.750000 ( 2.763401)
2 1.900000 0.250000 2.150000 ( 2.152947)
3 1.870000 0.230000 2.100000 ( 2.112615)
10 1.750000 0.320000 2.070000 ( 2.066013)
30 1.780000 0.260000 2.040000 ( 2.050358)
50 1.770000 0.250000 2.020000 ( 2.021323)
100 1.700000 0.300000 2.000000 ( 2.014740)
test_cache_batch
user system total real
1 2.060000 0.240000 2.300000 ( 2.301558)
2 1.870000 0.290000 2.160000 ( 2.164925)
3 1.890000 0.210000 2.100000 ( 2.109823)
10 1.770000 0.280000 2.050000 ( 2.047593)
30 1.850000 0.170000 2.020000 ( 2.035191)
50 1.800000 0.210000 2.010000 ( 2.016329)
100 1.790000 0.230000 2.020000 ( 2.027382)
好像这么写更好
def read_in_batch(total, batch_size)
(1..total).each_slice(batch_size) do |slice|
batch = slice.map { |i| "user:#{i}:counter" }
Rails.cache.read_multi(*batch)
end
end
#10 楼 @vincent 我测了一下,改 read_in_batch n, 1 以后,数据如下
user system total real
1 0.010000 0.000000 0.010000 ( 0.018565)
10 0.230000 0.010000 0.240000 ( 0.229515)
30 0.020000 0.000000 0.020000 ( 0.019327)
50 0.020000 0.000000 0.020000 ( 0.020574)
100 0.030000 0.000000 0.030000 ( 0.032168)
用原方法,本机数据如下
user system total real
1 0.770000 0.110000 0.880000 ( 0.880746)
10 0.010000 0.000000 0.010000 ( 0.015449)
30 0.020000 0.000000 0.020000 ( 0.016035)
50 0.030000 0.000000 0.030000 ( 0.032530)
100 0.030000 0.000000 0.030000 ( 0.025726)
和你的结果一致。
不知道怎么解释前一种情况,直觉上文中的解释说不通
都使用 read_in_batch 时:
去掉 1,“大时间”在 1, 2 行交错
user system total real
10 0.020000 0.000000 0.020000 ( 0.011991)
30 0.230000 0.010000 0.240000 ( 0.235225)
50 0.010000 0.000000 0.010000 ( 0.017332)
100 0.030000 0.000000 0.030000 ( 0.021796)
user system total real
10 0.250000 0.000000 0.250000 ( 0.258668)
30 0.010000 0.000000 0.010000 ( 0.012602)
50 0.020000 0.000000 0.020000 ( 0.020062)
100 0.020000 0.000000 0.020000 ( 0.014228)
去掉 10 , “大时间”在 1, 2 行交错
user system total real
1 0.270000 0.000000 0.270000 ( 0.271896)
30 0.010000 0.000000 0.010000 ( 0.012453)
50 0.010000 0.000000 0.010000 ( 0.013926)
100 0.030000 0.000000 0.030000 ( 0.028314)
user system total real
1 0.020000 0.000000 0.020000 ( 0.013825)
30 0.180000 0.000000 0.180000 ( 0.178828)
50 0.010000 0.000000 0.010000 ( 0.012010)
100 0.010000 0.000000 0.010000 ( 0.012555)
1 里面为啥不用 read_in_batch n, 1
学习了,就喜欢这种好文章。最近刷 leetcode109 Convert Sorted List to Binary Search Tree 发现一般递归算法会导致内存超标。对如何过毫无思路 T_T
@@x = " some other value"
这句把 @@x
“拉”到了两个 class 的外面,这句之后 @@x
就属于 toplevel class variable 了。变成所有类共享了。
把他移到最上面可以发现输出变成 y
了
puts(eval("@mystr << @@x", ob1.getBinding)) #=> ob1 string y
puts(eval("@mystr << @@x", ob2.getBinding)) #=> ob2 string y
puts(eval("@mystr << @@x", ob3.getBinding)) #=> ob3 string y
解释器还会给出警告:
xxxxxx.rb:xx: warning: class variable access from toplevel
已投 ( ゜- ゜) つロ 乾杯~