Index: XIOS/dev/dev_olga/src/filter/temporal_filter.cpp
===================================================================
--- XIOS/dev/dev_olga/src/filter/temporal_filter.cpp	(revision 983)
+++ XIOS/dev/dev_olga/src/filter/temporal_filter.cpp	(revision 1158)
@@ -5,34 +5,21 @@
 namespace xios
 {
+  static func::CFunctor* createFunctor(const std::string& opId, bool ignoreMissingValue, double missingValue, CArray<double, 1>& tmpData);
+
   CTemporalFilter::CTemporalFilter(CGarbageCollector& gc, const std::string& opId,
                                    const CDate& initDate, const CDuration samplingFreq, const CDuration samplingOffset, const CDuration opFreq,
                                    bool ignoreMissingValue /*= false*/, double missingValue /*= 0.0*/)
     : CFilter(gc, 1, this)
-    , samplingFreq(samplingFreq)
+    , functor(createFunctor(opId, ignoreMissingValue, missingValue, tmpData))
+    , isOnceOperation(functor->timeType() == func::CFunctor::once)
+    , isInstantOperation(functor->timeType() == func::CFunctor::instant)
+    // If we can optimize the sampling when dealing with an instant functor we do it
+    , samplingFreq((isInstantOperation && samplingFreq == TimeStep && samplingOffset == NoneDu) ? opFreq : samplingFreq)
+    , samplingOffset((isInstantOperation && samplingFreq == TimeStep && samplingOffset == NoneDu) ? opFreq - initDate.getRelCalendar().getTimeStep() : samplingOffset)
     , opFreq(opFreq)
-    , nextSamplingDate(initDate + samplingOffset + initDate.getRelCalendar().getTimeStep())
-    , nextOperationDate(initDate + opFreq)
+    , nextSamplingDate(initDate + this->samplingOffset + initDate.getRelCalendar().getTimeStep())
+    , nextOperationDate(initDate + this->samplingOffset + opFreq)
     , isFirstOperation(true)
   {
-#define DECLARE_FUNCTOR(MType, mtype) \
-    if (opId.compare(#mtype) == 0) \
-    { \
-      if (ignoreMissingValue) \
-      { \
-        functor.reset(new func::C##MType(tmpData, missingValue)); \
-      } \
-      else \
-      { \
-        functor.reset(new func::C##MType(tmpData)); \
-      } \
-    }
-
-#include "functor_type.conf"
-
-    if (!functor)
-      ERROR("CTemporalFilter::CTemporalFilter(CGarbageCollector& gc, const std::string& opId, ...)",
-            << "\"" << opId << "\" is not a valid operation.");
-
-    isOnceOperation = (functor->timeType() == func::CFunctor::once);
   }
 
@@ -43,26 +30,42 @@
     if (data[0]->status != CDataPacket::END_OF_STREAM)
     {
-      const bool usePacket = isOnceOperation ? isFirstOperation : (data[0]->date >= nextSamplingDate);
+      bool usePacket, outputResult, copyLess;
+      if (isOnceOperation)
+        usePacket = outputResult = copyLess = isFirstOperation;
+      else
+      {
+        usePacket = (data[0]->date >= nextSamplingDate);
+        outputResult = (data[0]->date + samplingFreq > nextOperationDate);
+        copyLess = (isInstantOperation && usePacket && outputResult);
+      }
+
       if (usePacket)
       {
-        if (!tmpData.numElements())
-          tmpData.resize(data[0]->data.numElements());
+        if (!copyLess)
+        {
+          if (!tmpData.numElements())
+            tmpData.resize(data[0]->data.numElements());
 
-        (*functor)(data[0]->data);
+          (*functor)(data[0]->data);
+        }
 
         nextSamplingDate = nextSamplingDate + samplingFreq;
       }
 
-      const bool outputResult = isOnceOperation ? isFirstOperation : (data[0]->date + samplingFreq > nextOperationDate);
       if (outputResult)
       {
-        functor->final();
+        if (!copyLess)
+        {
+          functor->final();
 
-        packet = CDataPacketPtr(new CDataPacket);
-        packet->date = data[0]->date;
-        packet->timestamp = data[0]->timestamp;
-        packet->status = data[0]->status;
-        packet->data.resize(tmpData.numElements());
-        packet->data = tmpData;
+          packet = CDataPacketPtr(new CDataPacket);
+          packet->date = data[0]->date;
+          packet->timestamp = data[0]->timestamp;
+          packet->status = data[0]->status;
+          packet->data.resize(tmpData.numElements());
+          packet->data = tmpData;
+        }
+        else
+          packet = data[0];
 
         isFirstOperation = false;
@@ -73,3 +76,36 @@
     return packet;
   }
+
+  bool CTemporalFilter::isDataExpected(const CDate& date) const
+  {
+    return isOnceOperation ? isFirstOperation : (date >= nextSamplingDate || date + samplingFreq > nextOperationDate);
+  }
+
+  static func::CFunctor* createFunctor(const std::string& opId, bool ignoreMissingValue, double missingValue, CArray<double, 1>& tmpData)
+  {
+    func::CFunctor* functor = NULL;
+
+    double defaultValue = ignoreMissingValue ? std::numeric_limits<double>::quiet_NaN() : missingValue;
+
+#define DECLARE_FUNCTOR(MType, mtype) \
+    if (opId.compare(#mtype) == 0) \
+    { \
+      if (ignoreMissingValue) \
+      { \
+        functor = new func::C##MType(tmpData, defaultValue); \
+      } \
+      else \
+      { \
+        functor = new func::C##MType(tmpData); \
+      } \
+    }
+
+#include "functor_type.conf"
+
+    if (!functor)
+      ERROR("createFunctor(const std::string& opId, ...)",
+            << "\"" << opId << "\" is not a valid operation.");
+
+    return functor;
+  }
 } // namespace xios
