From: shugo@... (MAEDA Shugo) Date: 1998-12-09T19:23:20+09:00 Subject: [ruby-dev:3786] pack("m") --Multipart_Wed_Dec__9_19:23:28_1998-1 Content-Type: text/plain; charset=ISO-2022-JP 前田です。 >>>>> In [ruby-dev:3773] >>>>> "前田" == MAEDA Shugo san wrote: 前田> pack.cのencodes()は、ループの中で毎回str_cat()を呼ぶために、 前田> 何度もreallocするせいで少し遅いような気がするのですが、どうでしょう。 バッファリングするようにしたらかなり速くなりました:-) $ time /usr/local/bin/ruby -e '[open("ruby").read].pack("m")' real 0m3.651s user 0m2.400s sys 0m1.250s $ time ./ruby -e '[open("ruby").read].pack("m")' real 0m0.891s user 0m0.750s sys 0m0.140s パッチを添付します。 あと、文字列の範囲外のメモリにアクセスしないように変更してあります。 --Multipart_Wed_Dec__9_19:23:28_1998-1 Content-Type: application/octet-stream; type=patch Content-Disposition: attachment; filename="pack.c.diff" Content-Transfer-Encoding: 7bit --- pack.c.orig Wed Dec 9 16:47:44 1998 +++ pack.c Wed Dec 9 19:08:37 1998 @@ -513,38 +513,41 @@ int len; int type; { - char hunk[4]; + char *buff = ALLOCA_N(char, len * 4 / 3 + 6); + int i = 0; char *p, *pend; char *trans = type == 'u' ? uu_table : b64_table; int padding; if (type == 'u') { - *hunk = len + ' '; - str_cat(str, hunk, 1); + buff[i++] = len + ' '; padding = '`'; } else { padding = '='; } - while (len > 0) { - hunk[0] = trans[077 & (*s >> 2)]; - hunk[1] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; - hunk[2] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))]; - hunk[3] = trans[077 & s[2]]; - str_cat(str, hunk, 4); + while (len >= 3) { + buff[i++] = trans[077 & (*s >> 2)]; + buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; + buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))]; + buff[i++] = trans[077 & s[2]]; s += 3; len -= 3; } - p = RSTRING(str)->ptr; - pend = RSTRING(str)->ptr + RSTRING(str)->len; - if (len == -1) { - pend[-1] = padding; + if (len == 2) { + buff[i++] = trans[077 & (*s >> 2)]; + buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; + buff[i++] = trans[077 & (((s[1] << 2) & 074) | (('\0' >> 6) & 03))]; + buff[i++] = padding; } - else if (len == -2) { - pend[-2] = padding; - pend[-1] = padding; + else if (len == 1) { + buff[i++] = trans[077 & (*s >> 2)]; + buff[i++] = trans[077 & (((*s << 4) & 060) | (('\0' >> 4) & 017))]; + buff[i++] = padding; + buff[i++] = padding; } - str_cat(str, "\n", 1); + buff[i++] = '\n'; + str_cat(str, buff, i); } static char hex_table[] = "0123456789ABCDEF"; --Multipart_Wed_Dec__9_19:23:28_1998-1 Content-Type: text/plain; charset=ISO-2022-JP -- 前田 修吾 (mailto:shugo@aianet.ne.jp) --Multipart_Wed_Dec__9_19:23:28_1998-1--