end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転します

Devel::Sizeで変数のメモリ量を計測したら、でかくて驚いた

select *
from
 (select hm.member_id, sum(val) as val
  from $tbl_name ss
  join hems_member hm
   on (hm.update_date<=? and
       ss.member_sid=hm.member_sid)
  where ?<=ss.date_month and ss.date_month<=?
  group by hm.member_id ) as ss_summary
where val=0;

↑このような副問い合わせのsqlを書いて...
sqlの副問い合わせは、index scan しないので好きではありませんが
外側のselect をperl で書いたら、どうなるんだろう?」と思ったことがきっかけです。

そこで、perlのDevel::Sizeと、cのsizeof()で、変数のメモリサイズを調べてみた。

cのsizeof()

#include <stdio.h>

main() {
  printf("INT VAL MEMORY SIZE\n");
  int int_val[5] = {999,999999,999999999};
  int i;
  for(i = 0 ; i <= 2 ; i++){
    printf("%d bytes\n", sizeof(int_val[i]));
  }

  printf("STRING VAL MEMORY SIZE\n");
  char str_val[3][9] = {"999","999999","999999999"};
  for(i = 0 ; i <= 2 ; i++){
    printf("%d bytes\n", sizeof(str_val[i]));
  }
}

実谷結果

INT VAL MEMORY SIZE
4 bytes
4 bytes
4 bytes
STRING VAL MEMORY SIZE
9 bytes
9 bytes
9 bytes

そりゃそうだ。

次にperlのDevel::Size

#!/usr/local/bin/perl
use strict;
use utf8;
use Devel::Size qw/size/;

main();

sub main {
    print "INT VAL MEMORY SIZE\n";
    my @int_vals = (999,999_999,999999999);
    for my $int_val ( @int_vals ){
	print total_size($int_val)," bytes\n";
    }

    print "STRING VAL MEMORY SIZE\n";
    my @str_vals = ('999','999999','999999999');
    for my $str_val ( @str_vals ){
	print total_size($str_val)," bytes\n";
    }
}

実行結果

INT VAL MEMORY SIZE
16 bytes
16 bytes
16 bytes
STRING VAL MEMORY SIZE
28 bytes
32 bytes
36 bytes

って、オイ! perlは食い過ぎでしょ!