[macruby-changes] [5216] MacRuby/trunk/pack.c
source_changes at macosforge.org
source_changes at macosforge.org
Mon Jan 31 15:41:31 PST 2011
Revision: 5216
http://trac.macosforge.org/projects/ruby/changeset/5216
Author: lsansonetti at apple.com
Date: 2011-01-31 15:41:31 -0800 (Mon, 31 Jan 2011)
Log Message:
-----------
improve all Array#pack cases (except 'w') by pre-allocating the result bytestring
Modified Paths:
--------------
MacRuby/trunk/pack.c
Modified: MacRuby/trunk/pack.c
===================================================================
--- MacRuby/trunk/pack.c 2011-01-31 23:20:40 UTC (rev 5215)
+++ MacRuby/trunk/pack.c 2011-01-31 23:41:31 UTC (rev 5216)
@@ -432,6 +432,14 @@
* Z | Same as ``a'', except that null is added with *
*/
+#define PRE_ALLOCATE(bstr, len) \
+ do { \
+ const long datalen = rb_bstr_length(data); \
+ rb_bstr_resize(bstr, datalen + len); \
+ rb_bstr_set_length(bstr, datalen); \
+ } \
+ while (0)
+
static VALUE
pack_pack(VALUE ary, SEL sel, VALUE fmt)
{
@@ -546,12 +554,14 @@
case 'A': /* arbitrary binary string (ASCII space padded) */
case 'Z': /* null terminated string */
if (plen >= len) {
+ PRE_ALLOCATE(data, len + 1);
rb_bstr_concat(data, (const UInt8 *)ptr, len);
if (p[-1] == '*' && type == 'Z') {
rb_bstr_concat(data, (const UInt8 *)nul10, 1);
}
}
else {
+ PRE_ALLOCATE(data, len);
rb_bstr_concat(data, (const UInt8 *)ptr, plen);
len -= plen;
while (len >= 10) {
@@ -571,6 +581,7 @@
j = (len - plen + 1)/2;
len = plen;
}
+ PRE_ALLOCATE(data, len);
for (i=0; i++ < len; ptr++) {
if (*ptr & 1)
byte |= 128;
@@ -602,6 +613,7 @@
j = (len - plen + 1)/2;
len = plen;
}
+ PRE_ALLOCATE(data, len);
for (i=0; i++ < len; ptr++) {
byte |= *ptr & 1;
if (i & 7)
@@ -632,6 +644,7 @@
j = (len + 1) / 2 - (plen + 1) / 2;
len = plen;
}
+ PRE_ALLOCATE(data, len);
for (i=0; i++ < len; ptr++) {
if (ISALPHA(*ptr))
byte |= (((*ptr & 15) + 9) & 15) << 4;
@@ -663,6 +676,7 @@
j = (len + 1) / 2 - (plen + 1) / 2;
len = plen;
}
+ PRE_ALLOCATE(data, len);
for (i=0; i++ < len; ptr++) {
if (ISALPHA(*ptr))
byte |= ((*ptr & 15) + 9) & 15;
@@ -689,6 +703,7 @@
case 'c': /* signed char */
case 'C': /* unsigned char */
+ PRE_ALLOCATE(data, len);
while (len-- > 0) {
char c;
@@ -700,6 +715,7 @@
case 's': /* signed short */
case 'S': /* unsigned short */
+ PRE_ALLOCATE(data, len * NATINT_LEN(short,2));
while (len-- > 0) {
short s;
@@ -711,6 +727,7 @@
case 'i': /* signed int */
case 'I': /* unsigned int */
+ PRE_ALLOCATE(data, len * NATINT_LEN(int,4));
while (len-- > 0) {
long i;
@@ -722,6 +739,7 @@
case 'l': /* signed long */
case 'L': /* unsigned long */
+ PRE_ALLOCATE(data, len * NATINT_LEN(long,4));
while (len-- > 0) {
long l;
@@ -733,6 +751,7 @@
case 'q': /* signed quad (64bit) int */
case 'Q': /* unsigned quad (64bit) int */
+ PRE_ALLOCATE(data, len * QUAD_SIZE);
while (len-- > 0) {
char tmp[QUAD_SIZE];
@@ -743,6 +762,7 @@
break;
case 'n': /* unsigned short (network byte-order) */
+ PRE_ALLOCATE(data, len * NATINT_LEN(short,2));
while (len-- > 0) {
unsigned short s;
@@ -754,6 +774,7 @@
break;
case 'N': /* unsigned long (network byte-order) */
+ PRE_ALLOCATE(data, len * NATINT_LEN(long,4));
while (len-- > 0) {
unsigned long l;
@@ -765,6 +786,7 @@
break;
case 'v': /* unsigned short (VAX byte-order) */
+ PRE_ALLOCATE(data, len * NATINT_LEN(short,2));
while (len-- > 0) {
unsigned short s;
@@ -776,6 +798,7 @@
break;
case 'V': /* unsigned long (VAX byte-order) */
+ PRE_ALLOCATE(data, len * NATINT_LEN(long,4));
while (len-- > 0) {
unsigned long l;
@@ -788,6 +811,7 @@
case 'f': /* single precision float in native format */
case 'F': /* ditto */
+ PRE_ALLOCATE(data, len * sizeof(float));
while (len-- > 0) {
float f;
@@ -798,6 +822,7 @@
break;
case 'e': /* single precision float in VAX byte-order */
+ PRE_ALLOCATE(data, len * sizeof(float));
while (len-- > 0) {
float f;
FLOAT_CONVWITH(ftmp);
@@ -810,6 +835,7 @@
break;
case 'E': /* double precision float in VAX byte-order */
+ PRE_ALLOCATE(data, len * sizeof(double));
while (len-- > 0) {
double d;
DOUBLE_CONVWITH(dtmp);
@@ -823,6 +849,7 @@
case 'd': /* double precision float in native format */
case 'D': /* ditto */
+ PRE_ALLOCATE(data, len * sizeof(double));
while (len-- > 0) {
double d;
@@ -833,6 +860,7 @@
break;
case 'g': /* single precision float in network byte-order */
+ PRE_ALLOCATE(data, len * sizeof(float));
while (len-- > 0) {
float f;
FLOAT_CONVWITH(ftmp);
@@ -845,6 +873,7 @@
break;
case 'G': /* double precision float in network byte-order */
+ PRE_ALLOCATE(data, len * sizeof(double));
while (len-- > 0) {
double d;
DOUBLE_CONVWITH(dtmp);
@@ -858,6 +887,7 @@
case 'x': /* null byte */
grow:
+ PRE_ALLOCATE(data, len);
while (len >= 10) {
rb_bstr_concat(data, (const UInt8 *)nul10, 10);
len -= 10;
@@ -890,6 +920,7 @@
break;
case 'U': /* Unicode character */
+ PRE_ALLOCATE(data, 6 * len);
while (len-- > 0) {
SIGNED_VALUE l;
char buf[8];
@@ -925,18 +956,7 @@
len = len / 3 * 3;
}
- // Try to guess the final size of the bytestring and pre-allocate
- // its content, to avoid too much frequent memory reallocations
- // during the encoding loop.
- do {
- const long datalen = rb_bstr_length(data);
- const long newdatalen = datalen
- + ((plen / len)
- * (len * 4 / 3 + 6));
- rb_bstr_resize(data, newdatalen);
- rb_bstr_set_length(data, datalen);
- }
- while (false);
+ PRE_ALLOCATE(data, (plen / len) * (len * 4 / 3 + 6));
while (plen > 0) {
long todo;
@@ -973,6 +993,7 @@
len = 1;
/* FALL THROUGH */
case 'p': /* pointer to string */
+ PRE_ALLOCATE(data, len * sizeof(char *));
while (len-- > 0) {
char *t;
from = NEXTFROM;
@@ -992,6 +1013,7 @@
break;
case 'w': /* BER compressed integer */
+ // TODO: data bstr pre-allocation
while (len-- > 0) {
unsigned long ul;
VALUE bufdata = rb_bstr_new();
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20110131/2bc4847d/attachment-0001.html>
More information about the macruby-changes
mailing list