メインコンテンツまでスキップ

「Array」タグの記事が3件件あります

全てのタグを見る

PHP: 添字配列の初期化、出力、代入

· 約2分
Yu Sasaki
Enterprise Security Manager / Advisor

ソースコード

<?php
// 添字配列の初期化
$numbers = array(0, 3, 100, 2087123454, ); // 数値のみ(末尾要素のカンマは省略可)
$strings = array('Jon', 'Mery', 'Sun', 'Ren', ); // 文字列のみ
$numstrs = array(1, 1.0, '1', ); // 複数型混合(数値、少数、文字列)
$empty = array(); // 空の配列
// var_dumpで構造を確認
echo '$numbers == ';
var_dump($numbers);
echo '$strings == ';
var_dump($strings);
echo '$numstrs == ';
var_dump($numstrs);
echo '$empty == ';
var_dump($empty);
echo PHP_EOL;
// 配列の要素を出力
echo $numbers[2], PHP_EOL;
echo $strings[0], PHP_EOL;
echo $numstrs[2], PHP_EOL, PHP_EOL;
// foreach で配列の要素を先頭から順に出力
foreach ($numbers as $val) {
echo $val, PHP_EOL;
}
echo PHP_EOL;
// 配列の要素への代入
$strings[0] = 'Mike';
$empty[] = 'Jon'; // 空のブラケットを用いると要素の追加となる
echo $strings[0], PHP_EOL;
echo $empty[0], PHP_EOL;
?>

実行結果

$numbers == array(4) {
[0]=>
int(0)
[1]=>
int(3)
[2]=>
int(100)
[3]=>
int(2087123454)
}
$strings == array(4) {
[0]=>
string(3) "Jon"
[1]=>
string(4) "Mery"
[2]=>
string(3) "Sun"
[3]=>
string(3) "Ren"
}
$numstrs == array(3) {
[0]=>
int(1)
[1]=>
float(1)
[2]=>
string(1) "1"
}
$empty == array(0) {
}
100
Jon
1
3
100
2087123454
Mike
Jon

リファレンス

ArrayListのコンストラクタに初期容量を指定することで要素の追加処理を高速化

· 約3分
Yu Sasaki
Enterprise Security Manager / Advisor

javaのArrayListのコンストラクタにはオーバーロードで幾つかの種類がありますが、その一つに以下のようなものがあります。

ArrayList(int initialCapacity) 指定された初期サイズで空のリストを作成します。 Java 2 Platform SE 1.3: クラス ArrayList

ArrayListは動的に容量を確保しますが、そのメモリ割り当て処理はCPUにそれなりの負荷を与えます。そこで、予め格納する容量が分かっていればコンストラクタの引数で初期容量を指定することで、その負荷の掛かる処理を事前に省くことが出来、その結果、処理時間の短縮につながります。

ちなみに、このint initialCapacityの容量の単位はコレクションの要素数です(2008/3/7修正)。

以下に初期容量を指定したときとしないときのでの処理時間を計るJavaのソースコードを示します。

import java.io.*; // for BufferedReader
import java.util.*; // for ArrayList
public class DumpFile {
/**
* @param args : 入力ファイル名
*/
public static void main(String[] args) {
String line;
ArrayList filelist = new ArrayList();
ArrayList mlist = new ArrayList(4000000); // 計測用リスト:4898304バイトのファイル
if (args.length < 1) { // コマンドライン引数の数
System.out.println("How to use: java DumpFile [filename]");
System.exit(1);
}
try {
BufferedReader br = new BufferedReader(new FileReader(args[0]));
while ((line = br.readLine()) != null) {
filelist.add(line); // 入力ファイルは一行=一要素として格納
//System.out.println(line);
}
br.close();
}
catch (Exception e) {
System.err.println(e.toString());
}
int n = filelist.size();
long start = System.currentTimeMillis(); // 処理時間の計測開始
for (int i = 0; i < n; i++) {
//System.out.println(list.get(i));
mlist.add(filelist.get(i));
}
long end = System.currentTimeMillis();
System.out.println("実行時間:" + (end - start) + "ms");
/*for (int i = 0; i < n; i++) {
System.out.println(mlist.get(i));
}*/
}
}

入力ファイルは日本語単語405,000語で4898304Byteです。

…< 中略>…
楽観
楽観さ
楽観し
楽観した
楽観したら
楽観したり
楽観したろう
楽観しちゃ
…< 中略>…

結果は、

mlistに対して初期容量を指定しない場合:17ms mlistに対して初期容量を指定した 場合:8ms

となり、今回の場合は処理時間を1/2に短縮できていることが分かりました。 ちなみに、ArrayListのメモリ動的割り当て容量は、現在の容量の1.5倍のようです。

int newCapacity = (oldCapacity * 3)/2 + 1; ArrayList#ensureCapacityメソッド内の一文 - ArrayList.java 1.56 06/04/21

参考にしたサイト

  • Java 入門 | ArrayList クラス

追記(2008/3/7):

1.コンストラクタでインスタンス容量を指定するものとして、StringBufferクラスがあります。これも、

StringBuffer sb = new StringBuffer(40000); // 40KByteを確保

のように指定します。

これによって、append()やinsert()によって予め割り当てられたバッファを越す際に呼び出されるメモリ動的割り当て処理を軽減することが出来ます。

2.ArrayListのコンストラクタに引数を指定しない場合は10個の要素を持った配列が作られます。

/** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this(10); } ArrayList.java 1.56 06/04/21