Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Can this be done any faster
Message
De
11/02/2006 06:53:06
 
 
À
10/02/2006 08:50:33
Suhas Hegde
Dental Surgeon
Sirsi, Inde
Information générale
Forum:
Visual FoxPro
Catégorie:
Base de données, Tables, Vues, Index et syntaxe SQL
Versions des environnements
Visual FoxPro:
VFP 6 SP5
Database:
Visual FoxPro
Divers
Thread ID:
01095428
Message ID:
01095627
Vues:
13
Suhas,

you have already received a few good answers.
Since you only gave some code WITHOUT much information on the base scenario,
I can think of quite a few alternative angles, some of them along the lines of the other posts.

First of all: My impression is, that you always recalculate all the data in Bhav_data ?
If this is for something like running averages, you should ONLY need to calculate anything not calculated before!
Such an approach would tremendously cut down the times, since most of the 1000 date-records of each symbol would be left alone!
On that assumption using something quite similar to your basic approach (which is better to understand and read later on!) feasible.

The following is based on Jim's approach, not tested and only enhanced by cutting out the "use in" and
optimizing the inner scan (which would benefit more if the reccount of cursor s1 is not cut down too much...)
lParameter tDateStart
or if not coded as a procedure
tDateStart = blabla...

create cursor gainloss(date D,gain f(10,2),loss f(10,2))
INDEX ON Date TAG Date1
select symbol from bhav_data group by 1 into cursor distsymbol nofilter
local lnLastClose, lnCounter, lcTotalCount
lnCounter = 0
lcTotalCount = TRANSFORM(RECCOUNT("distsymbol"),"999,999,999")
WAIT WINDOW TRANSFORM(lnCounter,"999,999,999") + " of " + lcTotalCount + " records"
scan
	lnCounter = lnCounter + 1
        * Slowest thing you can do is write to screen so let's do it every 50 records instead of every record
        IF MOD(lnCounter,50) = 0
           WAIT WINDOW TRANSFORM(lnCounter,"999,999,999") + " of " + lcTotalCount + " records"
        ENDIF
        SELECT GainLoss
        ZAP
        *-- get ONLY the records NOT CALCULATED before / needed to get the values for calculation!
	select date,close from bhav_data ;
            where PADR(symbol,20) = distsymbol.symbol ;
                  and date>=m.tDateStart
            into cursor s1

        *-- since you work consecutively, pre-fill lnLastClose and work alway of the current record!
	lnLastClose = s1.close
        SKIP

	SCAN Rest While ! EOF()
                lnDiff = lnLastClose - s1.close
                INSERT INTO GainLoss (Date, Gain, Loss) ;
                              VALUES (S1.Date,IIF(m.lndiff>0,m.lndiff,0),IIF(m.lnDiff<=0,-m.lnDiff,0))
                lnLastClose = s1.close
	endscan
        *-- DON'T close the tables
	* use in s1

	*-- update bhav_data one of the ways you already do or written by others: 
        *-- here experimentation is your best bet to show the fastest way. 
        *-- Probably another (compound) index like  PADR(symbol,20)+dtoc(date)
        *-- will be your best bet IF that doesn't slow down other insert operations
        *-- done to the table. Keep the big picture in mind.
        *-- But DON'T close the temp tables <g>
	* use in gainloss
endscan
* The following WAIT just makes the numbers equal at the end of the processing 
* if there aren't a number of recs divisable by 50
WAIT WINDOW TRANSFORM(lnCounter,"999,999,999") + " of " + lcTotalCount + " records"
If you CANNOT keep the calculations done one earlier dates and always have to recalculate ALL,
something along the lines Cetin mentioned would be my guess to go,
since you save the time to build those 1000 s1 with reccount() of 1000 - even if it is not so clear how it is done.
Based on Chuck's code I'ld again make the second scan as fast as possible:
*-- I assume symbol is c(20)
CREATE CURSOR ac_gainloss (symbol C(20), date D, gain f(10,2), loss f(10,2)
INDEX ON ON symbol + DTOS(date) TAG symbol1

SELECT bhav_data
SET ORDER TO symbol1 && symbol + DTOS(date)
lc_symbol = SPACE(0)

SCAN
   *-- Set key value
   IF .NOT. lc_symbol == bhav_data->symbol
      lc_symbol = bhav_data->symbol
      WAIT WINDOW lc_symbol NOWAIT
   ENDIF

   *-- Prefill 
   lnLastclose = bhav_data->close
   *-- Move to next day
   SKIP
   *-- Loop though all the data for this symbol
   SCAN WHILE bhav_data->symbol = lc_symbol

     *-- calculate with Chuck' approach or with something similar to your old one or Jim's
     

     *-- Prefill 
     lnLastclose = bhav_data->close
   ENDSCAN
   *-- If using Jim's or your old approach, update from temp cursor and clean temp cursor here
ENDSCAN
*-- If Chuck's approach is better for your data structure, update here
Again, I am not sure which way of summarizing is the best for your scenario, but the gathering of data is optimized.

my 0.02 EUR

thomas
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform