[#31692] cannot run test-all — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
9 messages
2007/09/01
[#31697] Re: [ruby-list:43970] 次の1.8.6 — Tadayoshi Funaba <tadf@...>
> * [ruby-dev:31379]がペンディング
10 messages
2007/09/01
[#31699] Re: [ruby-list:43970] 次の1.8.6
— Urabe Shyouhei <shyouhei@...>
2007/09/01
Tadayoshi Funaba wrote:
[#31700] Re: [ruby-list:43970] 次の1.8.6
— Tadayoshi Funaba <tadf@...>
2007/09/01
> > WIN32OLE も Time も担当でないし、この報告が何をいいたいのかもよくわか
[#31703] Re: [ruby-list:43970] 次の1.8.6
— Urabe Shyouhei <shyouhei@...>
2007/09/01
Tadayoshi Funaba wrote:
[#31706] Re: [ruby-list:43970] 次の1.8.6
— Tadayoshi Funaba <tadf@...>
2007/09/01
> 今後サポートを続けるべきかはご判断にお任せします。OLEで使われてるん
[#31709] [BUG] non-initialized struct — Tanaka Akira <akr@...>
以下のようにすると [BUG] が出ます。
6 messages
2007/09/02
[#31715] string literal encoding — Nobuyoshi Nakada <nobu@...>
なかだです。
12 messages
2007/09/02
[#31716] Re: string literal encoding
— Yukihiro Matsumoto <matz@...>
2007/09/02
まつもと ゆきひろです
[#31729] packed st_table — Nobuyoshi Nakada <nobu@...>
なかだです。
8 messages
2007/09/04
[#31734] [m17n] String#chop & String#succ — Nobuyoshi Nakada <nobu@...>
なかだです。
2 messages
2007/09/05
[#31744] [m17n] String#encode — Nobuyoshi Nakada <nobu@...>
なかだです。
7 messages
2007/09/06
[#31768] shellescape — "Akinori MUSHA" <knu@...>
shellwords.rb に shellescape() 等を追加しようと思います。
5 messages
2007/09/10
[#31774] RSTRING(value)->ptr == NULL ? — Tietew <tietew+ruby-dev@...>
Tietew です。
7 messages
2007/09/11
[#31778] Re: RSTRING(value)->ptr == NULL ?
— Yukihiro Matsumoto <matz@...>
2007/09/12
まつもと ゆきひろです
[#31781] `scan': character encodings differ (ArgumentError) — Kouhei Sutou <kou@...>
須藤です。
5 messages
2007/09/15
[#31787] 文字列のinspect — eklerni <eklerni@...>
eklerniといいます。
5 messages
2007/09/15
[#31798] generator from Enumerable#map — "Yusuke ENDOH" <mame@...>
遠藤と申します。
7 messages
2007/09/19
[#31810] rb_obj_is_kind_of — Tanaka Akira <akr@...>
rb_obj_is_kind_of の TYPE(cl) ですが、[ruby-dev:31805] の例
5 messages
2007/09/21
[#31815] 文字列の式展開 — eklerni <eklerni@...>
eklerniといいます。
6 messages
2007/09/22
[#31835] Kernel#` is blocked with Ruby/GLib2 on Intel Mac — Kouhei Sutou <kou@...>
須藤です。
5 messages
2007/09/24
[#31842] 拡張ライブラリ内での SIGVTALRM — とみたまさひろ <tommy@...>
とみたです。
10 messages
2007/09/24
[#31848] huge `if' dumps core — "Yusuke ENDOH" <mame@...>
遠藤と申します。
5 messages
2007/09/24
[#31850] meta programming might dump core — "Yusuke ENDOH" <mame@...>
遠藤と申します。
2 messages
2007/09/24
[#31853] optimize T_OBJECT space — Tanaka Akira <akr@...>
T_OBJECT なインスタンスで、インスタンス変数の名前をクラス側
7 messages
2007/09/25
[#31880] Re: optimize T_OBJECT space
— Tanaka Akira <akr@...>
2007/09/28
In article <87r6kne799.fsf@fsij.org>,
[ruby-dev:31761] Re: packed st_table
From:
Tanaka Akira <akr@...>
Date:
2007-09-08 12:22:27 UTC
List:
ruby-dev #31761
In article <20070904084324.A224BE03D3@mail.bc9.jp>,
Nobuyoshi Nakada <nobu@ruby-lang.org> writes:
> 田中さんに「Hashの順序はどっちでもいいからこっちをやれ」といわれ
> たので、st_tableのentries_packedを一般化してみました。
測ってみたところ、どうも 1要素の場合しかメモり節約の効果が見
られないので調べてみたところ、以下のような修正が必要なようで
す。add_direct_packed の先頭のコードはよくわかりませんでした。
ST_DEFAULT_INIT_TABLE_SIZE 以外でも packed を可能にするには、
struct st_table の head のところにサイズを入れればいいはずで
すが、やってません。
--- st.c.nakada 2007-09-08 16:23:47.000000000 +0900
+++ st.c 2007-09-08 21:02:11.000000000 +0900
@@ -153,6 +153,8 @@ stat_col()
(((r) < 3 || (st_data_t)(table)->bins[(i)+2] == (hash_val)) &&\
EQUAL((table), (st_data_t)(table)->bins[i], (key)))
+static void unpack_entries(register st_table *table);
+
st_table*
st_init_table_with_size(const struct st_hash_type *type, int size)
{
@@ -175,6 +177,9 @@ st_init_table_with_size(const struct st_
tbl->num_bins = 0;
tbl->bins = calloc(size, sizeof(st_table_entry*));
tbl->head = 0;
+ if (size != ST_DEFAULT_INIT_TABLE_SIZE) {
+ unpack_entries(tbl);
+ }
return tbl;
}
@@ -349,10 +354,12 @@ add_direct_packed(register st_table *tab
{
unsigned int i;
+ /*
if (table->num_bins >= ST_DEFAULT_INIT_TABLE_SIZE / r * r) {
table->bins = xrealloc(table->bins, sizeof(struct st_table_entry *) * (table->num_bins+r));
}
- else if (!PACKABLE(table, table->num_bins+r)) {
+ else */
+ if (!PACKABLE(table, table->num_bins/r+1)) {
return 0;
}
i = table->num_bins;
@@ -457,6 +464,8 @@ st_copy(st_table *old_table)
}
*new_table = *old_table;
+ if (old_table->entries_packed)
+ num_bins = ST_DEFAULT_INIT_TABLE_SIZE;
new_table->bins = calloc(num_bins, sizeof(st_table_entry*));
if (new_table->bins == 0) {
@@ -600,11 +609,12 @@ st_cleanup_safe(st_table *table, st_data
const unsigned int r = PACKED_RATIO(table);
for (i = j = 0; i < table->num_bins; i += r) {
if ((st_data_t)table->bins[i] != never && i > j) {
- memcpy(&table->bins[j], table->bins[i],
+ memcpy(&table->bins[j], &table->bins[i],
sizeof(st_table_entry *) * r);
- j++;
+ j += r;
}
}
+ table->num_bins = j;
return;
}
@@ -648,7 +658,7 @@ st_foreach(st_table *table, int (*func)(
case ST_DELETE:
table->num_entries--;
if (i >= (table->num_bins -= r)) return 0;
- memmove(&table->bins[i], &table->bins[i+1],
+ memmove(&table->bins[i], &table->bins[i+r],
sizeof(struct st_table_entry*) * (table->num_bins-i));
break;
}
@@ -721,7 +731,7 @@ st_reverse_foreach(st_table *table, int
case ST_DELETE:
table->num_entries--;
if (i >= (table->num_bins -= r)) break;
- memmove(&table->bins[i], &table->bins[i+1],
+ memmove(&table->bins[i], &table->bins[i+r],
sizeof(struct st_table_entry*) * (table->num_bins-i));
break;
}
で、測定結果ですが、一番効くはずの 3要素の Hash では以下のよ
うになります。
節約しないと以下のように 199Mbytes かかります。
% time ./ruby -e 'a = []; 1000000.times {|i| a << {0=>i,1=>i,2=>i} }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize: 199312 kB
./ruby -e 7.37s user 0.31s system 99% cpu 7.711 total
節約すると以下のように 105Mbytes で済みます。
% time ./ruby -e 'a = []; 1000000.times {|i| a << {0=>i,1=>i,2=>i} }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize: 105468 kB
./ruby -e 4.43s user 0.15s system 99% cpu 4.607 total
もちろん、速度も 7.7秒から 4.6秒に高速化します。
では、11word の bins からあふれて linked list に変わる 4要素
ならどうか、というと、節約しない場合は以下のようになります。
% time ./ruby -e 'a = []; 1000000.times {|i| a << {0=>i,1=>i,2=>i,3=>i} }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize: 230468 kB
./ruby -e 9.09s user 0.33s system 99% cpu 9.461 total
節約した場合は以下のようになります。
% time ./ruby -e 'a = []; 1000000.times {|i| a << {0=>i,1=>i,2=>i,3=>i} }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize: 230472 kB
./ruby -e 9.73s user 0.34s system 99% cpu 10.117 total
どちらも使用メモリが 230Mbytes でほぼ同じなのは予想どおりで、
速度低下は 9.5秒から 10.1秒というくらいです。
より現実的な例として REXML を... と思ったのですが、REXML は
今は character encodings differ により動かないようなので、測
定できませんでした。うぅむ。
--
[田中 哲][たなか あきら][Tanaka Akira]