Actors Ring
今度はRingにしてみた。
import scala.actors._ import scala.actors.Actor._ import java.lang.management._ object actor_ring extends Application { class myactor(no:int, nb:Actor, d:Boolean) extends Actor { var neighbour:Actor = nb var dec:boolean = d var start_time:long = 0 def this(no:int, nb:Actor) = this(no, nb, false) def setNeighbour(nb:Actor) = {neighbour = nb} def setStartTime(st:long) = {start_time = st} def act() { react { case Tuple2('Msg, i:int) => { if (dec == true) { val m = ManagementFactory.getMemoryMXBean.getHeapMemoryUsage val now = System.nanoTime() println(((now - start_time) / 1000000000.0) + "[sec], " + m.getUsed/1024/1024 + "MB") start_time = now neighbour ! Tuple2('Msg, i-1) } else { neighbour ! Tuple2('Msg, i) } if (i == 1) exit() act() } } } } def make_chain(n:int):List[myactor] = { val first_at = new myactor(n, null, true) first_at.start make_chain(n-1, first_at, List(first_at)) } def make_chain(n:int, next:myactor, chain:List[myactor]):List[myactor] = { n match { case 0 => chain case _ => { val at = new myactor(n, next) at.start make_chain(n-1, at, at :: chain) } } } val num = 100000 val loop_num = 10 println("START") val m = ManagementFactory.getMemoryMXBean.getHeapMemoryUsage println(m.toString) val mnh = ManagementFactory.getMemoryMXBean.getNonHeapMemoryUsage println(mnh.toString) val st = System.nanoTime() val at_chain = make_chain(num) println*1 at ! Tuple2('Msg, loop_num) }
Pen4 2GHz OS:Ubuntu
Scala2.6.1 Final
において
10万Actorsを10周させてみると
START init = 16777216(16384K) used = 573728(560K) committed = 16711680(16320K) max = 266403840(260160K) init = 33718272(32928K) used = 14967328(14616K) committed = 34177024(33376K) max = 121634816(118784K) 15.669[microsec/create-actor] 1.210402832[sec], 25MB 1.364063691[sec], 26MB 1.02014446[sec], 32MB 0.80601815[sec], 40MB 1.301092184[sec], 29MB 0.763399419[sec], 37MB 1.25066676[sec], 26MB 0.78286096[sec], 34MB 1.243149875[sec], 24MB 0.718866898[sec], 27MB
な感じ。
ガベコレに0.5秒程度かかっている模様。
ちなみに、act関数の作りを
def act() { react { : act() } }
から
def act() { loop { react { : } } }
に変えると
START init = 16777216(16384K) used = 573808(560K) committed = 16711680(16320K) max = 266403840(260160K) init = 33718272(32928K) used = 14967432(14616K) committed = 34177024(33376K) max = 121634816(118784K) 17.997[microsec/create-actor] 1.640117266[sec], 30MB 1.117640128[sec], 42MB 1.78655447[sec], 33MB 1.131797293[sec], 43MB 1.672665112[sec], 34MB 1.128878803[sec], 44MB 1.676959597[sec], 36MB 1.102893978[sec], 48MB 1.720956371[sec], 37MB 0.775506848[sec], 41MB
となって、ちょっと遅い
def act() { receive { : act() } }
にすると、
http://jijixi.azito.com/cgi-bin/diary/index.rb?date=20070622#p02
にも説明があるように、大量のスレッドが必要になるためか、かえってこない。
(というか、帰ってくるまで待てない。100くらいまでが限度)
*1:System.nanoTime()-st)/num/1000.0 + "[microsec/create-actor]") val at = at_chain.head at_chain.last.setNeighbour(at) at_chain.last.setStartTime(System.nanoTime(