From: "Shot (Piotr Szotkowski)" Date: 2009-09-19T19:04:52+09:00 Subject: Re: How can I cache param-based Enumerator call results? --LQksG6bCIzRHxTLp Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Shot (Piotr Szotkowski): > I=E2=80=99m trying to cache a lazy-evaluated, param-based Enumerator call= s. > Considering the following code: > def arith a, b > Enumerator.new do |yielder| > ['+', '*'].each do |oper| > sleep 1 # simulates a param-based, long-running process > yielder.yield [oper, eval("#{a} #{oper} #{b}")] > end > end > end > [[1,2], [3,4], [5,6], [1,2], [3,4], [5,6], [7,8]].each do |a, b| > arith(a,b).each do |oper, result|=20 > puts "#{a} #{oper} #{b} =3D #{result}" > end > end > should take about 14 seconds to run, with arith() lazily returning the > sum and product of its params. Still, if you look closely, arith(1,2), > arith(3,4) and arith(5,6) are called twice; if there was caching of > the yielded values there would be no need to recompute these sums > and products (and the whole process would take around eight seconds > instead). I ended up doing the below, which nicely caches the stuff outside the Enumerator. Any improvements (I have a feeling that the each=E2=80=A6puts= =E2=80=A6end blocks can be DRY-ed up by factoring them out) most welcome, of course! def arith a, b Enumerator.new do |yielder| ['+', '*'].each do |oper| sleep 1 # simulates a param-based, long-running process yielder.yield [oper, eval("#{a} #{oper} #{b}")] end end end cache =3D {} [[1,2], [3,4], [5,6], [1,2], [3,4], [5,6], [7,8]].each do |a, b| if cache[[a,b]] cache[[a,b]].each do |oper, result| puts "#{a} #{oper} #{b} =3D #{result}" end else cache[[a,b]] =3D [] arith(a,b).each do |oper, result| puts "#{a} #{oper} #{b} =3D #{result}" cache[[a,b]] << [oper, result] end end end =E2=80=94 Shot --=20 This sentence contradicts itself =E2=80=93 no actually it doesn=E2=80=99t. [Douglas Hofstadter] --LQksG6bCIzRHxTLp Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkq0rL8ACgkQi/mCfdEo8Uq+wQCfdvVFAi7TxN/flMhzhreYn6UY y/gAoIE3cC1VZf9m0QhURd8aSOTTNlQb =wLME -----END PGP SIGNATURE----- --LQksG6bCIzRHxTLp--