Mercurial > cpython-lru_cache-weakref
diff Objects/unicodeobject.c @ 76128:489f252b1f8b
Close #14249: Use bit shifts instead of an union, it's more efficient.
Patch written by Serhiy Storchaka
| author | Victor Stinner <victor.stinner@gmail.com> |
|---|---|
| date | Thu, 05 Apr 2012 22:54:49 +0200 |
| parents | 2c514c382a2a |
| children | c20f604a2da6 |
line wrap: on
line diff
--- a/Objects/unicodeobject.c Thu Apr 05 13:31:12 2012 -0700 +++ b/Objects/unicodeobject.c Thu Apr 05 22:54:49 2012 +0200 @@ -5393,9 +5393,11 @@ #if (SIZEOF_LONG == 8) # define FAST_CHAR_MASK 0x8000800080008000L # define SWAPPED_FAST_CHAR_MASK 0x0080008000800080L +# define STRIPPED_MASK 0x00FF00FF00FF00FFL #elif (SIZEOF_LONG == 4) # define FAST_CHAR_MASK 0x80008000L # define SWAPPED_FAST_CHAR_MASK 0x00800080L +# define STRIPPED_MASK 0x00FF00FFL #else # error C 'long' size should be either 4 or 8! #endif @@ -5496,39 +5498,31 @@ int kind = PyUnicode_KIND(unicode); void *data = PyUnicode_DATA(unicode); while (_q < aligned_end) { - union { - unsigned long as_long; - unsigned short units[sizeof(long) / sizeof(short)]; - unsigned char bytes[sizeof(long)]; - } block, block_copy; + unsigned long block = * (unsigned long *) _q; Py_UCS4 maxch; - - block.as_long = *(unsigned long *) _q; if (native_ordering) { /* Can use buffer directly */ - if (block.as_long & FAST_CHAR_MASK) + if (block & FAST_CHAR_MASK) break; } else { /* Need to byte-swap */ - block_copy = block; - - if (block.as_long & SWAPPED_FAST_CHAR_MASK) + if (block & SWAPPED_FAST_CHAR_MASK) break; - block.bytes[0] = block_copy.bytes[1]; - block.bytes[1] = block_copy.bytes[0]; - block.bytes[2] = block_copy.bytes[3]; - block.bytes[3] = block_copy.bytes[2]; -#if (SIZEOF_LONG == 8) - block.bytes[4] = block_copy.bytes[5]; - block.bytes[5] = block_copy.bytes[4]; - block.bytes[6] = block_copy.bytes[7]; - block.bytes[7] = block_copy.bytes[6]; -#endif - } - maxch = Py_MAX(block.units[0], block.units[1]); + block = ((block >> 8) & STRIPPED_MASK) | + ((block & STRIPPED_MASK) << 8); + } + maxch = (Py_UCS2)(block & 0xFFFF); #if SIZEOF_LONG == 8 - maxch = Py_MAX(maxch, Py_MAX(block.units[2], block.units[3])); + ch = (Py_UCS2)((block >> 16) & 0xFFFF); + maxch = Py_MAX(maxch, ch); + ch = (Py_UCS2)((block >> 32) & 0xFFFF); + maxch = Py_MAX(maxch, ch); + ch = (Py_UCS2)(block >> 48); + maxch = Py_MAX(maxch, ch); +#else + ch = (Py_UCS2)(block >> 16); + maxch = Py_MAX(maxch, ch); #endif if (maxch > PyUnicode_MAX_CHAR_VALUE(unicode)) { if (unicode_widen(&unicode, maxch) < 0) @@ -5536,11 +5530,24 @@ kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); } - PyUnicode_WRITE(kind, data, outpos++, block.units[0]); - PyUnicode_WRITE(kind, data, outpos++, block.units[1]); +#ifdef BYTEORDER_IS_LITTLE_ENDIAN + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)(block & 0xFFFF)); #if SIZEOF_LONG == 8 - PyUnicode_WRITE(kind, data, outpos++, block.units[2]); - PyUnicode_WRITE(kind, data, outpos++, block.units[3]); + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)((block >> 16) & 0xFFFF)); + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)((block >> 32) & 0xFFFF)); + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)((block >> 48))); +#else + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)(block >> 16)); +#endif +#else +#if SIZEOF_LONG == 8 + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)((block >> 48))); + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)((block >> 32) & 0xFFFF)); + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)((block >> 16) & 0xFFFF)); +#else + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)(block >> 16)); +#endif + PyUnicode_WRITE(kind, data, outpos++, (Py_UCS2)(block & 0xFFFF)); #endif _q += SIZEOF_LONG; }
