Removal of string-based object resolution

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Removal of string-based object resolution

Andre Louw-2

Hi,

I notice that all the string-based object resolution have been removed from the SWIG wrapper files (calendars, currencies, daycounters). Is there an alternative mechanism that I'm missing to resolve specific implementations of these classes based on an input string?

I.e previously, in Python, something like "cal = Calendar('usa')" would resolve to the UnitedStates() implementation of Calendar. Without this mechanism I would have to resolve this in Python, which I'm assuming "off the cuff" would have a performance impact?

If there is no alternative, any objections to reworking this to include all the latest implementations?

Andre
Reply | Threaded
Open this post in threaded view
|

Re: Removal of string-based object resolution

Luigi Ballabio-2
On 2004.10.11 14:45, Andre Louw wrote:
> I notice that all the string-based object resolution have been removed
> from the SWIG wrapper files (calendars, currencies, daycounters). Is  
> there an alternative mechanism that I'm missing to resolve specific
> implementations of these classes based on an input string?

Andre,
        you can add the following in the .i file:

%extend Calendar {
    Calendar(const std::string& name) {
        if (name == "USA") return new Calendar(UnitedStates());
        else if ....
    }
}

to get back the old behavior. If you're worried about performance, you can  
tailor the above to your usage by checking first the calendars you use most  
frequently.


> Without this mechanism I would have to resolve this in Python, which I'm  
> assuming "off the cuff" would have a performance impact?

In principle, but I don't think it would matter much if you, say, create a  
Calendar, pass it to a Schedule, build a bond and price it---the creation  
overhead should be negligible compared to the work done later. Also, see  
below.


> If there is no alternative, any objections to reworking this to include
> all the latest implementations?

Well, on the one hand I was trying to remove redundancy and have one less  
thing to maintain. On the other hand, one might want to customize the  
strings used---because, say, his database uses different names, or he wants  
'USA' to mean the Bond market calendar rather than the Stock exchange, and  
that is more difficult if I write _my_ strings in stone--or in the  
wrappers, which is practically the same thing.  I'd suggest storing a few  
calendar instances in a Python dictionary when one loads the module, as in:

my_calendars = {
    'USA': UnitedStates(),
    'TARGET': TARGET(),
    ...
}

and use my_calendars[name] instead of Calendar(name). Or you can even  
write:

def _init_calendar(self,name):
    self.this = my_calendars[name]
    self.thisown = 0
Calendar.__init__ = _init_calendar

and keep using Calendar(name). This might actually improve performance, as  
you would get a reference to an already created calendar instead of  
allocating new memory in order to create one (*).


Later,
        Luigi


(*) technical note: the wrapper code could not be written simply as

if (name == "USA")  return new UnitedStates;

as the pointer would have been cast to Calendar* and later deleted as such.  
Since the Calendar class has no virtual destructor, the above would be  
undefined behavior according to the C++ standard. Instead, the code had to  
be written as:

if (name == "USA")  return new Calendar(UnitedStates());

i.e., an initialization, an allocation with new, and a copy---inefficient,  
and just plain twisted.