莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理
          最近重讀了《Programming Lua》,對協程做了重點復習。眾所周知,Ruby1.9引入了Fiber,同樣是coroutine,不過Ruby Fiber支持全對稱協程(通過fiber庫),而Lua只支持所謂半對稱協程。

          ??? 這里將對Lua、LuaJIT和Ruby Fiber的切換效率做個對比測試,測試場景很簡單:兩個coroutine相互切換達到5000萬次,統計每秒切換的次數,各測試多次取最佳。

          ??? lua的程序如下:
          ???
          c1=coroutine.create(function?()
          ?????????????????????
          while?true?do
          ???????????????????????coroutine
          .yield()
          ?????????????????????end
          ????????????????????end)

          c2
          =coroutine.create(function?()
          ?????????????????????
          while?true?do
          ???????????????????????coroutine
          .yield()
          ?????????????????????end
          ????????????????????end)

          local?start=os.clock()
          local?count=50000000

          for?i=1,count?do
          ?coroutine
          .resume(c1)
          ?coroutine
          .resume(c2)
          end

          print(4*count/(os.clock()-start))

          ??? 考慮到在循環中事實上發生了四次切換:main->c1,c1->main,main->c2,c2->main,因此乘以4。

          ??? Ruby Fiber的測試分兩種,采用transfer的例程如下:

          require?'fiber'
          require?'benchmark'

          Benchmark
          .bm?do?|x|
          ??MAX_COUNT
          =50000000
          ??f1
          =Fiber.new?do?|other,count|
          ?????
          while?count<MAX_COUNT
          ??????other
          ,count=other.transfer(Fiber.current,count.succ)
          ?????end
          ??end

          ??f2
          =Fiber.new?do?|other,count|
          ????
          while?count<MAX_COUNT
          ??????other
          ,count=other.transfer(Fiber.current,count.succ)
          ????end
          ??end

          ??x
          .report{
          ????f1
          .resume(f2,0)
          ??}
          end
          ???? Ruby Fiber采用resume/yield的例程如下:
          require?'benchmark'
          f1
          =Fiber.new?do
          ??
          while?true
          ????Fiber
          .yield
          ??end
          end
          f2
          =Fiber.new?do
          ??
          while?true
          ????Fiber
          .yield
          ??end
          end

          COUNT
          =50000000

          Benchmark
          .bm?do?|x|
          ??x
          .report{
          ?????COUNT
          .times?do
          ?????????f1
          .resume
          ?????????f2
          .resume
          ?????end
          ??}
          end



          ???? 測試環境:
          ????????? CPU :??? Intel(R) Core(TM)2 Duo CPU???? P8600? @ 2.40GHz
          ????????? Memory:? 3GB
          ????????? System :? Linux dennis-laptop 2.6.31-14-generic #48-Ubuntu SMP
          ????????? Lua??? : 5.1.4
          ????????? ruby? :? 1.9.1p378
          ????????? LuaJIT:? 1.1.5和2.0.0-beta2

          ????? 測試結果如下:
          ????
          ??Lua?LuaJIT 1.1.5
          ?LuaJIT 2.0.0-beta2
          ?ruby-transfer
          ?ruby-resume/yield
          ?次數?6123698?9354536?24875620?825491?969649


          ????? 結論:
          ????? 1、lua的協程切換效率都是百萬級別,luaJIT 2.0的性能更是牛叉,切換效率是原生lua的4倍,達到千萬級別。
          ????? 2、相形之下,Ruby Fiber的效率比較差了,十萬級別。
          ????? 3、Ruby使用transfer的效率比之resume/yield略差那么一點,排除一些測試誤差,兩者應該是差不多的,從ruby源碼上看resume/yield和transfer的調用是一樣的,resume還多了幾條指令。
          ????? 4、額外信息,Ruby Fiber和lua coroutine都只能跑在一個cpu上,這個測試肯定能跑滿一個cpu,內存占用上,lua也比ruby小很多。
          ?


          評論

          # re: Lua、LuaJIT Coroutine和Ruby Fiber的切換效率對比  回復  更多評論   

          2010-03-03 11:08 by 99書城
          暗示大家撒暗示

          # re: Lua、LuaJIT Coroutine和Ruby Fiber的切換效率對比  回復  更多評論   

          2010-03-04 14:38 by mryufeng
          Lua的coroutine設計上非常的輕量 確定就是單線程

          http://blog.yufeng.info
          主站蜘蛛池模板: 建宁县| 三门峡市| 封丘县| 庆阳市| 区。| 军事| 大渡口区| 阿鲁科尔沁旗| 股票| 阜宁县| 枣阳市| 巴塘县| 华蓥市| 临夏市| 汉阴县| 花莲县| 建平县| 永泰县| 峡江县| 晋城| 务川| 灵武市| 临澧县| 汝州市| 凌源市| 墨脱县| 柳江县| 无棣县| 平遥县| 平乐县| 陵川县| 新兴县| 临城县| 云阳县| 宁海县| 上饶市| 鄢陵县| 盐边县| 屏山县| 旺苍县| 聂拉木县|