a question, because I fail to get a proper solution myself.
I need to add / subtract large sets of FixedPoints sometimes. These are numbers with identical scale (say, 2, for currency values). Currently I have this method that **really** needs optimisation: balanceForEntry: anEntry | readEntries read sum | readEntries := self entries readStream. sum := self openingBalance amount. [read == anEntry] whileFalse: [(read := readEntries next) isVoid ifFalse: [sum := sum + read amount amount]]. ^Currency newAmount: sum Converting the FixedPoint to Float increases performance some. Anybody has better ideas? _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
It would be nice to do a timeprofile on this method and check which statement really needs the optimization..
I would say the next call to the stream may be more to contribute to the time consumed. The addition of two float/fixed point numbers may contribute even upto 25% additional time but for order of 10 million+ operations if the overall time taken is less than or about 1 sec.. you can find some directions..
Even the time profile report would help in giving any realistic suggestion. TimeProfiler profile: [ x times repeat: [... balanceForEntry: anEntry]] from AdvancedTools.. skrish On Sun, Oct 12, 2008 at 8:57 PM, Rob Vens <[hidden email]> wrote:
_______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Rob Vens-2
Bob, FixedPoint is a subclass
of Fraction. It inherits the semantics of Fraction and thus it runs an
expensive reducing algorithm (Euler) for it. Float is much faster, but it is
not exact by any means. What you can do it to
introduce a new Integer and scale based class, or even fixed scale class. This will
be much faster. Georg Georg Heeg eK, Dortmund
und Köthen, HR Dortmund A 12812 Tel. +49-3496-214328,
Fax +49-3496-214712 Von:
[hidden email] [mailto:[hidden email]] Im Auftrag von Rob Vens a question, because I fail to get a proper solution myself. _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Rob Vens-2
Hi Rob,
Can you keep the entries in cents rather than in dollars and cents? That way you can treat everything as an integer until display time.... -Anthony On 12-Oct-08, at 11:27 AM, Rob Vens wrote:
_______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Rob Vens-2
This is what we do in our system and it works well when stored with currency to keep track of actual number of minor units (2 for dollar, 0 for yen, etc). From: [hidden email] To: Rob Vens Cc: VWNC Sent: Sun Oct 12 15:06:25 2008 Subject: Re: [vwnc] optimisation of FixedPoint arithmetic Hi Rob, Can you keep the entries in cents rather than in dollars and cents? That way you can treat everything as an integer until display time.... -Anthony On 12-Oct-08, at 11:27 AM, Rob Vens wrote:
_______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Rob Vens-2
Method 3 below reduces the problem to integer arithmetic in the inner
loop (but adds the cost of dictionary accesses). It will get a *lot* slower if you have unlimited denominator values, inspect (numbers collect: [: ea| ea denominator]) asSet. In other words: the #roundedToScale in the input data has a large effect on the timing. If you are absolutely certain the denominators cover a fixed range you might be able to replace the dictionary accesses with array accesses which I show in #4. Everybody: See how many millions your customer can loose when you decide to use floating point in financial applications (results of #2 below). numbers := (Random new next: 1000000) collect: [:float | (float * 1000000 asFixedPoint: 2) roundedToScale]. time1 := Time millisecondsToRun: [ sum1 := numbers inject: 0 into: [:sum :each | sum + each]]. time2 := Time millisecondsToRun: [ sum2 := (numbers inject: 0 into: [:sum :each | sum + each asFloat]) asFixedPoint: 2]. time3 := Time millisecondsToRun: [ sum3 := ((numbers inject: IdentityDictionary new into: [:temps :each | temps at: each denominator put: (temps at: each denominator ifAbsent: [0]) + each numerator. temps]) associations inject: 0 into: [:sum :ass | ass value / ass key + sum]) asFixedPoint: 2]. time4 := Time millisecondsToRun: [ |t| t := (numbers inject: (Array new: 100 withAll: 0) into: [:temps :each | temps at: each denominator put: (temps at: each denominator ) + each numerator. temps]). sum4 := 0. t keysAndValuesDo: [:i :v | sum4 := sum4 + (v/i)]. sum4 := sum4 asFixedPoint: 2. ]. results := Array with: sum1 -> time1 with: sum2 -> time2 with: sum3 -> time3 with: sum4 -> time4 "#( 499836445147.47s->2061 499777961984.00s->437 499836445147.47s->568 499836445147.47s->419)" HTH, Reinout ------- On Oct 12, 2008, at 5:27 PM, Rob Vens wrote: > a question, because I fail to get a proper solution myself. > I need to add / subtract large sets of FixedPoints sometimes. These > are numbers with identical scale (say, 2, for currency values). > Currently I have this method that **really** needs optimisation: > > balanceForEntry: anEntry > > | readEntries read sum | > readEntries := self entries readStream. > sum := self openingBalance amount. > [read == anEntry] > whileFalse: > [(read := readEntries next) isVoid > ifFalse: [sum := sum + read amount amount]]. > ^Currency newAmount: sum > > Converting the FixedPoint to Float increases performance some. > Anybody has better ideas? > _______________________________________________ > vwnc mailing list > [hidden email] > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
Free forum by Nabble | Edit this page |