Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: Travers Naran Newsgroups: comp.lang.java.programmer Subject: Re: iteration blues Date: Thu, 03 Nov 2011 22:22:07 -0700 Organization: A noiseless patient Spider Lines: 64 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Fri, 4 Nov 2011 05:22:09 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="WHd9Ip4x0HUqzdKy50zSMQ"; logging-data="12906"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX181pPsZHHIpu7odRBg3Hl1z" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1 In-Reply-To: Cancel-Lock: sha1:xoKXtLQu1bFFd1FXxzcbmvnd0YA= Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:9508 On 03/11/2011 8:37 AM, bob wrote: > > public static void burnfire() { > Iterator i = particles.iterator(); > Vector removelist = new Vector(); > while (i.hasNext()) { > Particle p = i.next(); > p.move(); > p.timeleft--; > if (p.timeleft == 0) removelist.add(p); > > } > particles.removeAll(removelist); > > } > > I'm concerned about inefficiency in the burnfire function. Does > anyone know how to rewrite this quickly if particles was a linked > list? The main issue is that I'm not sure if removing items during > iteration messes up the iterator. What percentage of elements are removed each loop? If it's like 1 or 2 out of 1000's, then just your method will be OK. If you are eliminating like 50% of more per iteration, simply copy the value: ArrayList newParticleList = new ArrayList(particles.size()); for (Particle p : particles) { // Process p if (p.timeLeft > 0) newParticeList.add(p); } Another approach would be "buckets". You create a bucket for each life span so you know when you've reached nth iteration, the nth bucket particles are done. Pseudocode: ArrayList> buckets = new ArrayList>(MAX_LIFETIME); roundRobin = 0; for each frame do buckets.set(roundRobin, createNewParticles(n)); animate particles roundRobin = (roundRobin + 1) % MAX_LIFETIME; The reference to the ArrayList in slot n should disappear and the garbage collector can manage the rest. If your concerned about allocation/deallocation overhead, you can change createNewParticle to accept the old array list and let it "refresh" the list reusing not just the ArrayList but the actual Particle objects themselves. If the lifetimes are far more random with large gaps between groups of extinguishing particles (a sparse array), you could use a PriorityQueue with a comparitor sorting the particle's age up. Removing extinguished particles is O(log(n)) which is better than removing items one at a time from an ArrayList (which is O(n)).