[Scipy-svn] r3032 - trunk/Lib/sandbox/timeseries/src
scipy-svn@scip...
scipy-svn@scip...
Tue May 22 13:19:37 CDT 2007
Author: mattknox_ca
Date: 2007-05-22 13:19:32 -0500 (Tue, 22 May 2007)
New Revision: 3032
Modified:
trunk/Lib/sandbox/timeseries/src/c_tdates.c
Log:
optimized performance of dateinfo functions
Modified: trunk/Lib/sandbox/timeseries/src/c_tdates.c
===================================================================
--- trunk/Lib/sandbox/timeseries/src/c_tdates.c 2007-05-22 18:15:43 UTC (rev 3031)
+++ trunk/Lib/sandbox/timeseries/src/c_tdates.c 2007-05-22 18:19:32 UTC (rev 3032)
@@ -2429,19 +2429,169 @@
}
+/**************************************************************
+** The following functions are used by DateArray_getDateInfo **
+** to determine how many consecutive periods will have the **
+** same result **
+**************************************************************/
+
+// also used for qyear
+static int __skip_periods_year(int freq) {
+
+ int freq_group = get_freq_group(freq);
+
+ switch(freq_group)
+ {
+ case FR_QTR:
+ return 4;
+ case FR_MTH:
+ return 12;
+ case FR_WK:
+ return 51;
+ case FR_BUS:
+ return 260;
+ case FR_DAY:
+ return 365;
+ case FR_HR:
+ return 365*24;
+ case FR_MIN:
+ return 365*24*60;
+ case FR_SEC:
+ return 365*24*60*60;
+ default:
+ return 1;
+ }
+}
+
+static int __skip_periods_quarter(int freq) {
+
+ int freq_group = get_freq_group(freq);
+
+ switch(freq_group)
+ {
+ case FR_MTH:
+ return 3;
+ case FR_WK:
+ return 12;
+ case FR_BUS:
+ return 64;
+ case FR_DAY:
+ return 90;
+ case FR_HR:
+ return 90*24;
+ case FR_MIN:
+ return 90*24*60;
+ case FR_SEC:
+ return 90*24*60*60;
+ default:
+ return 1;
+ }
+}
+
+static int __skip_periods_month(int freq) {
+
+ int freq_group = get_freq_group(freq);
+
+ switch(freq_group)
+ {
+ case FR_WK:
+ return 3;
+ case FR_BUS:
+ return 20;
+ case FR_DAY:
+ return 28;
+ case FR_HR:
+ return 28*24;
+ case FR_MIN:
+ return 28*24*60;
+ case FR_SEC:
+ return 28*24*60*60;
+ default:
+ return 1;
+ }
+}
+
+// also used for day_of_year, day_of_week
+static int __skip_periods_day(int freq) {
+
+ int freq_group = get_freq_group(freq);
+
+ switch(freq_group)
+ {
+ case FR_HR:
+ return 24;
+ case FR_MIN:
+ return 24*60;
+ case FR_SEC:
+ return 24*60*60;
+ default:
+ return 1;
+ }
+}
+
+static int __skip_periods_week(int freq) {
+
+ int freq_group = get_freq_group(freq);
+
+ switch(freq_group)
+ {
+ case FR_BUS:
+ return 5;
+ case FR_DAY:
+ return 7;
+ case FR_HR:
+ return 7*28*24;
+ case FR_MIN:
+ return 7*28*24*60;
+ case FR_SEC:
+ return 7*28*24*60*60;
+ default:
+ return 1;
+ }
+}
+
+static int __skip_periods_hour(int freq) {
+
+ int freq_group = get_freq_group(freq);
+
+ switch(freq_group)
+ {
+ case FR_MIN:
+ return 60;
+ case FR_SEC:
+ return 60*60;
+ default:
+ return 1;
+ }
+}
+
+static int __skip_periods_minute(int freq) {
+
+ int freq_group = get_freq_group(freq);
+
+ switch(freq_group)
+ {
+ case FR_SEC:
+ return 60;
+ default:
+ return 1;
+ }
+}
+
PyObject *
DateArray_getDateInfo(PyObject *self, PyObject *args)
{
- int freq;
+ int freq, is_full, skip_periods, counter=1, val_changed=0;
char *info;
- PyArrayObject *array;
- PyArrayObject *newArray;
+ PyObject *prev_val=NULL;
+ PyArrayObject *array, *newArray;
PyArrayIterObject *iterSource, *iterResult;
PyObject* (*getDateInfo)(DateObject*, void*) = NULL;
- if (!PyArg_ParseTuple(args, "Ois:getDateInfo(array, freq, info)", &array, &freq, &info)) return NULL;
+ if (!PyArg_ParseTuple(args, "Oisi:getDateInfo(array, freq, info, is_full)",
+ &array, &freq, &info, &is_full)) return NULL;
newArray = (PyArrayObject *)PyArray_Copy(array);
iterSource = (PyArrayIterObject *)PyArray_IterNew((PyObject *)array);
@@ -2452,59 +2602,95 @@
{
case 'Y': //year
getDateInfo = &DateObject_year;
+ skip_periods = __skip_periods_year(freq);
break;
case 'F': //"fiscal" year
getDateInfo = &DateObject_qyear;
+ skip_periods = __skip_periods_year(freq);
break;
case 'Q': //quarter
getDateInfo = &DateObject_quarter;
+ skip_periods = __skip_periods_quarter(freq);
break;
case 'M': //month
getDateInfo = &DateObject_month;
+ skip_periods = __skip_periods_month(freq);
break;
case 'D': //day
getDateInfo = &DateObject_day;
+ skip_periods = __skip_periods_day(freq);
break;
case 'R': //day of year
getDateInfo = &DateObject_day_of_year;
+ skip_periods = __skip_periods_day(freq);
break;
case 'W': //day of week
getDateInfo = &DateObject_day_of_week;
+ skip_periods = __skip_periods_day(freq);
break;
case 'I': //week of year
getDateInfo = &DateObject_week;
+ skip_periods = __skip_periods_week(freq);
break;
case 'H': //hour
getDateInfo = &DateObject_hour;
+ skip_periods = __skip_periods_hour(freq);
break;
case 'T': //minute
getDateInfo = &DateObject_minute;
+ skip_periods = __skip_periods_minute(freq);
break;
case 'S': //second
getDateInfo = &DateObject_second;
+ skip_periods = 1;
break;
default:
return NULL;
}
- while (iterSource->index < iterSource->size) {
+ {
DateObject *curr_date;
PyObject *val, *dInfo;
- val = PyArray_GETITEM(array, iterSource->dataptr);
- curr_date = DateObject_FromFreqAndValue(freq, PyInt_AsLong(val));
- dInfo = getDateInfo(curr_date, NULL);
+ while (iterSource->index < iterSource->size) {
- PyArray_SETITEM(newArray, iterResult->dataptr, dInfo);
+ if ((val_changed == 0) ||
+ (is_full == 0) ||
+ (prev_val == NULL) ||
+ (counter >= skip_periods)) {
- Py_DECREF(val);
- Py_DECREF(curr_date);
- Py_DECREF(dInfo);
+ val = PyArray_GETITEM(array, iterSource->dataptr);
+ curr_date = DateObject_FromFreqAndValue(freq, PyInt_AsLong(val));
+ dInfo = getDateInfo(curr_date, NULL);
- PyArray_ITER_NEXT(iterSource);
- PyArray_ITER_NEXT(iterResult);
+ if ((prev_val != NULL) &&
+ (PyInt_AsLong(prev_val) != PyInt_AsLong(dInfo))) {
+ val_changed = 1;
+ counter = 0;
+ }
+
+ Py_DECREF(val);
+ Py_DECREF(curr_date);
+
+ if (prev_val != NULL) {
+ Py_DECREF(prev_val);
+ }
+
+ prev_val = dInfo;
+ }
+
+ PyArray_SETITEM(newArray, iterResult->dataptr, dInfo);
+
+ PyArray_ITER_NEXT(iterSource);
+ PyArray_ITER_NEXT(iterResult);
+
+ counter += 1;
+ }
}
+ if (prev_val != NULL) {
+ Py_DECREF(prev_val);
+ }
Py_DECREF(iterSource);
Py_DECREF(iterResult);
More information about the Scipy-svn
mailing list