mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-10 16:20:42 +00:00
Minor performance optimisations.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@19462 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
9e5bc129ed
commit
ffa9b78a57
2 changed files with 111 additions and 2 deletions
|
@ -5,6 +5,7 @@
|
|||
so it works when the default character encoding is not the same as
|
||||
the internal 8-bit encoding.
|
||||
* Source/GSString.m: New function to externalize a string.
|
||||
implementations of init with format for concrete classes.
|
||||
|
||||
2004-06-03 David Ayers <d.ayers@inode.at>
|
||||
|
||||
|
|
|
@ -95,8 +95,7 @@ Many optimizations, such as retaining instead of copying, and using pointers
|
|||
to another strings _contents buffer, are valid only if this flag is set.
|
||||
|
||||
GSCString, an abstract class that stores the string as 8-bit data in the
|
||||
internal encoding. GSCString and its subclasses are used only if
|
||||
intEnc==defEnc.
|
||||
internal encoding.
|
||||
*/
|
||||
@interface GSCString : GSString
|
||||
{
|
||||
|
@ -453,6 +452,89 @@ setup(void)
|
|||
}
|
||||
}
|
||||
|
||||
- (id) initWithFormat: (NSString*)format
|
||||
locale: (NSDictionary*)locale
|
||||
arguments: (va_list)argList
|
||||
{
|
||||
unsigned char buf[2048];
|
||||
GSStr_t f;
|
||||
unichar fbuf[1024];
|
||||
unichar *fmt = fbuf;
|
||||
size_t len;
|
||||
GSStr me;
|
||||
|
||||
|
||||
/*
|
||||
* First we provide an array of unichar characters containing the
|
||||
* format string. For performance reasons we try to use an on-stack
|
||||
* buffer if the format string is small enough ... it almost always
|
||||
* will be.
|
||||
*/
|
||||
len = [format length];
|
||||
if (len >= 1024)
|
||||
{
|
||||
fmt = objc_malloc((len+1)*sizeof(unichar));
|
||||
}
|
||||
[format getCharacters: fmt];
|
||||
fmt[len] = '\0';
|
||||
|
||||
/*
|
||||
* Now set up 'f' as a GSMutableString object whose initial buffer is
|
||||
* allocated on the stack. The GSFormat function can write into it.
|
||||
*/
|
||||
f.isa = GSMutableStringClass;
|
||||
f._zone = NSDefaultMallocZone();
|
||||
f._contents.c = buf;
|
||||
f._capacity = sizeof(buf);
|
||||
f._count = 0;
|
||||
f._flags.wide = 0;
|
||||
f._flags.free = 0;
|
||||
GSFormat(&f, fmt, argList, locale);
|
||||
if (fmt != fbuf)
|
||||
{
|
||||
objc_free(fmt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't use noCopy because f._contents.u may be memory on the stack,
|
||||
* and even if it wasn't f._capacity may be greater than f._count so
|
||||
* we could be wasting quite a bit of space. Better to accept a
|
||||
* performance hit due to copying data (and allocating/deallocating
|
||||
* the temporary buffer) for large strings. For most strings, the
|
||||
* on-stack memory will have been used, so we will get better performance.
|
||||
*/
|
||||
if (f._flags.wide == 1)
|
||||
{
|
||||
me = (GSStr)NSAllocateObject(GSUnicodeInlineStringClass,
|
||||
f._count*sizeof(unichar), GSObjCZone(self));
|
||||
me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
|
||||
me->_count = f._count;
|
||||
me->_flags.wide = 1;
|
||||
me->_flags.free = 1;
|
||||
memcpy(me->_contents.u, f._contents.u, f._count*sizeof(unichar));
|
||||
}
|
||||
else
|
||||
{
|
||||
me = (GSStr)NSAllocateObject(GSCInlineStringClass, f._count,
|
||||
GSObjCZone(self));
|
||||
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
|
||||
me->_count = f._count;
|
||||
me->_flags.wide = 0;
|
||||
me->_flags.free = 1;
|
||||
memcpy(me->_contents.c, f._contents.c, f._count);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the string had to grow beyond the initial buffer size, we must
|
||||
* release any allocated memory.
|
||||
*/
|
||||
if (f._flags.free == 1)
|
||||
{
|
||||
NSZoneFree(f._zone, f._contents.c);
|
||||
}
|
||||
return (id)me;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace self with an inline string matching the sort of information
|
||||
* given.
|
||||
|
@ -3022,6 +3104,32 @@ agree, create a new GSUnicodeInlineString otherwise.
|
|||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithFormat: (NSString*)format
|
||||
locale: (NSDictionary*)locale
|
||||
arguments: (va_list)argList
|
||||
{
|
||||
unichar fbuf[1024];
|
||||
unichar *fmt = fbuf;
|
||||
size_t len;
|
||||
|
||||
/*
|
||||
* First we provide an array of unichar characters containing the
|
||||
* format string. For performance reasons we try to use an on-stack
|
||||
* buffer if the format string is small enough ... it almost always
|
||||
* will be.
|
||||
*/
|
||||
len = [format length];
|
||||
if (len >= 1024)
|
||||
{
|
||||
fmt = objc_malloc((len+1)*sizeof(unichar));
|
||||
}
|
||||
[format getCharacters: fmt];
|
||||
fmt[len] = '\0';
|
||||
|
||||
GSFormat((GSStr)self, fmt, argList, locale);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (int) intValue
|
||||
{
|
||||
if (_flags.wide == 1)
|
||||
|
|
Loading…
Reference in a new issue