• #14 楼 @limkurn 什么意思,说详细一点吧

  • #12 楼 @zlx_star 好主意我来贴 @zlx_star 贴好了

  • #12 楼 @roclv 你是怎么做到改变背景颜色的?

  • 如果区分 普通关注 和 关注大 V 分别存两个 Set,这样可以省掉 求交集的一步

  • IP 地址转换方法 at 2015年06月09日

    建议用代码块包起来

  • #1 楼 @meeasyhappy #2 楼 @lgn21st #4 楼 @huacnlee #9 楼 @rei

    谢谢大家提供参考标准,我会努力的

  • #8 楼 @kgen 对,是 dev

  • #6 楼 @kabie 大概是我写的渣渣

  • #3 楼 @prajnamas 试了一下挺好用的

  • 骑士今天赢了! at 2015年06月09日

    viva la BACA!!!

  • #12 楼 @xiaoronglv 看了下时间。。。是来不了了。。。住松江略远

  • #11 楼 @vincent 看“然后”这一段里面的做法,是同一个思路啊 (๑• . •๑) 学习了,期待更多分享

  • 可以在 contoller 中用 view_context 对象来访问所有的 helper 方法

  • 不知道极米投影仪行不行?

  • 这不是和天面试的差不多╭(°A°`)╮

  • #1 楼 @jicheng1014 我也遇到这个问题,多谢

  • 使用 Rails 构建 API 实践 at 2015年06月01日

    请问楼主 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] 的操作

  • #5 楼 @vincent 例子的测试结果应该是由于 只有第一个测试真的去读了缓存。。。

    读取单个也可以用 read_muti, 而且比 read 快一些

  • #10 楼 @vincent 测试代码:

    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)
    

    结论:

    1. 在读一个数据的时候,read_multi 比 read 稳定快
    2. 你的结论好像不成立,不存在 n + 1 的现象,该现象应该是由于代码 bug 导致的。生产环境的现象我没法解释。。

    后续:

    其实上面的测试还是有问题,并没有读全部的 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 其实读的是 n - 1 个数据

    改正: read_in_batch n 其实读的不是 n 个数据

  • #8 楼 @vincent bug.

    if i + 1 % batch_size == 0
    

    应该为

    if (i + 1) % batch_size == 0
    

    我机器上测 ruby 2.2 上面的写法永远不会 == 0

  • #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

  • #1 楼 @hooopo 智慧被启迪了

  • How Ruby Uses Memory at 2015年05月28日

    学习了,就喜欢这种好文章。最近刷 leetcode109 Convert Sorted List to Binary Search Tree 发现一般递归算法会导致内存超标。对如何过毫无思路 T_T

  • #1 楼 @clarkyi merge! 是比较快的吧

  • 元编程 基础方法整理 at 2015年05月23日

    #8 楼 @lifuzho 好像

    @@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
    
    
  • 已投 ( ゜- ゜) つロ 乾杯~