Re: [Pyobjc-dev] NSDecimalNumber to the next level
Brought to you by:
ronaldoussoren
From: Pierce T.W. I. <pi...@tw...> - 2004-03-10 21:08:16
|
On Mar 10, 2004, at 12:16 PM, b.bum wrote: > On Mar 10, 2004, at 11:08 AM, Pierce T.Wetter III wrote: >> How so? NSNumbers are still an object, and I think that NSDecimal >> actually only uses the minimum amount of memory necessary. >> >> Remember this would only be necessary when passing a python number >> back to objective c. > > NSNumber & NSValue are designed as a minimal encapsulation of a C > scalar type. NSDecimalNumber can represent any number that can be > expressed as mantissa x 10 exponent where mantissa is a decimal > integer up to 38 digits long, and exponent is an integer between -128 > and 127. Yes, that's true, but not relevant, because we're going the right direction in that we're converting a python type to representation that is larger then what it cares about. There are two issues to my mind: Memory: NSNumber(int) is basically struct { objc_object *_isa; int value; } While NSDecimalNumber is struct { objc_object *_isa; NSDecimal dcvalue; } Except NSDecimal is a variable size structure, so while its larger then sizeof(int), the size of any number representable by by an int turns out to be smaller then then the maximum NSDecimal size. Performance: [NSNumber(double) doubleValue] [NSNumber(int) doubleValue] is slower then [NSDecimalNumber doubleValue] But since you're already doing a method call and going into/out of python, I don't think its that big a deal... > > Though, given that this will only come into play when passing a python > number back to Obj-C, the performance penalty will be a lot > smaller.... Here are the changes. objc_support: lines 1342:1356 WAS: } else if (PyObjCBool_Check(argument)) { *(id *) datum = [NSNumber numberWithBool:PyInt_AS_LONG (argument)]; } else if (PyInt_Check (argument)) { *(id *) datum = [NSNumber numberWithLong:PyInt_AS_LONG (argument)]; } else if (PyFloat_Check (argument)) { *(id *) datum = [NSNumber numberWithDouble:PyFloat_AS_DOUBLE (argument)]; } else if (PyLong_Check(argument)) { /* XXX: What if the value doesn't fit into a * 'long long' */ *(id *) datum = [NSNumber numberWithLongLong:PyLong_AsLongLong(argument)]; NOW: } else if (PyObjCBool_Check(argument)) { *(id *) datum = [NSDecimalNumber numberWithBool:PyInt_AS_LONG (argument)]; } else if (PyInt_Check (argument)) { *(id *) datum = [NSDecimalNumber numberWithLong:PyInt_AS_LONG (argument)]; } else if (PyFloat_Check (argument)) { *(id *) datum = [NSDecimalNumber numberWithDouble:PyFloat_AS_DOUBLE (argument)]; } else if (PyLong_Check(argument)) { /* XXX: What if the value doesn't fit into a * 'long long' */ *(id *) datum = [NSDecimalNumber numberWithLongLong:PyLong_AsLongLong(argument)]; |