ホーム 主筆 その他ソフト その他情報 Syuhitu.org English

Windows関連

スクリーンセーバー作成法

半透明ウインドウの性能

bootfont.bin

キャビネット形式

ウインドウスタイルをいじる

Java製ソフトをServiceに登録する

イベントログにメッセージを出力する

コントロールパネルにアイコンを追加する

スクリプトによる拡張1

スクリプトによる拡張2

ガジェットの作成

大容量メモリ

メモリ搭載量の下限に挑む

スパースファイルにする

表示されるアイコンの種類を調べてみた

メモリマップIOとエラー処理

ファイルを作る順番と速度の関係

Cryptography API: Next Generationを使う

Windows 10のアクセントカラー

iSCSIディスクにバックアップを取る

サーバプロセスを分離して実装する

サーバプロセスを分離して実装する - F#

レジストリに大量に書き込む

Solaris関連

OpenGL

Solaris設定

ディレクトリの読み込み

主筆プラグイン開発

マルチスレッドでの開発

door

音を出す

Blade100の正しい虐め方

パッケージの作成

画像入出力

BMPファイル

ICOファイル

ANIファイル

JPEGファイル

減色アルゴリズム

減色アルゴリズムの並列化

その他アルゴリズムなど

自由軸回転

Base64

文字列操作

CPU利用率の取得

正規表現ライブラリ

メタボールを作る

メタボールを作る2

正規表現とNFA・DFA

C言語の構文解析

液晶ディスプレイを解体してみた

iSCSIの理論と実装

単一フォルダにファイルを沢山作る

USB-HUBのカスケード接続

SafeIntの性能

VHDファイルのフォーマット

USBメモリに書き込み続けてみた

ファイルを作る順番と速度の関係

2016年1月23日公開

噂によれば、複数のフォルダにファイルをたくさん作るときには、フォルダ単位で順番にファイルを作った方が早いらしい。

つまり、フォルダ1の下にファイル1、2、3を作って、次にフォルダ2の下にファイル1、2、3を作るという順番にするべきであって、フォルダ1のファイル1、フォルダ2の下のファイル1、フォルダ3の下のファイル1という順にするべきではないという。

図にするとこうなる。

例えて言うなら深さ優先である。この順ならば早いという。

例えて言うなら幅優先である。この順だと遅いという。

直感的に言っても、まぁそうなのかもしれない。だが、本当にそうなのか、本当だとしたらどれぐらい違いうのか、実際にやってみた。

条件

フォルダやファイルを作成する対象としては、USB3.0接続の64GBのUSBメモリを使用している。それを、以下の条件でフォーマットしている。

深い根拠はないが、Visual Studio 2010のF#でプログラムを作って実行してみた。

やってみる

深さ優先のプログラム例と結果。

Microsoft(R) F# 2.0 Interactive ビルド 4.0.40219.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

ヘルプを表示するには次を入力してください: #help;;

> open System.IO;;
> #time "on";;

--> 現在タイミングはオンです

> // ディレクトリを作成する
ignore (
  List.map ( sprintf "f:\\dir_%03d" ) [0..255] 
    |> List.map Directory.CreateDirectory
);;
リアル: 00:00:01.042、CPU: 00:00:00.140、GC gen0: 0, gen1: 0, gen2: 0
val it : unit = ()
> // ファイルを作成する
let cfile ( a : int ) ( b : int ) =
    File.WriteAllText( sprintf "f:\\dir_%03d\\file_%03d.txt" a b, sprintf "%d\n" b );;
リアル: 00:00:00.000、CPU: 00:00:00.000、GC gen0: 0, gen1: 0, gen2: 0

val cfile : int -> int -> unit

> ignore (
  List.map ( fun a -> ( List.map ( cfile a ) [0..255] ) ) [0..255] 
);;
リアル: 00:31:00.840、CPU: 00:00:42.875、GC gen0: 159, gen1: 158, gen2: 2
val it : unit = ()

FSIだと白黒なわけだがそれだと寂しいから、色は俺が適当につけている。

それはいいとして、256個のフォルダの下に256個ずつ(つまり合計で65,536個)のファイルを作るのに1,860秒かかっている。

できたファイルの更新日付を確認しても、まぁ作る順番は間違っていないと考えたい。

次は、幅優先のプログラム例と結果。

Microsoft(R) F# 2.0 Interactive ビルド 4.0.40219.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

ヘルプを表示するには次を入力してください: #help;;

> open System.IO;;
> #time "on";;

--> 現在タイミングはオンです

> // ディレクトリを作成する
ignore (
  List.map ( sprintf "f:\\dir_%03d" ) [0..255] 
    |> List.map Directory.CreateDirectory
);;
リアル: 00:00:02.140、CPU: 00:00:00.078、GC gen0: 0, gen1: 0, gen2: 0
val it : unit = ()
> // ファイルを作成する
let cfile ( a : int ) ( b : int ) =
    File.WriteAllText( sprintf "f:\\dir_%03d\\file_%03d.txt" b a, sprintf "%d\n" b );;
リアル: 00:00:00.000、CPU: 00:00:00.000、GC gen0: 0, gen1: 0, gen2: 0

val cfile : int -> int -> unit

> ignore (
  List.map ( fun a -> ( List.map ( cfile a ) [0..255] ) ) [0..255] 
);;
リアル: 00:25:23.211、CPU: 00:00:43.687、GC gen0: 159, gen1: 157, gen2: 2
val it : unit = ()

やっていることはほぼ同じ。唯一の違いは、ファイルを出力する際に指定するファイル名だけである。ファイル名を生成するときに、フォルダ名とファイル名で使用する通番の指定を入れ替えただけである。

処理時間は1,523秒だった。変わんないどころか、むしろ早い。繰り返しになるが、ファイルの更新日付を見る限り、作る順番は想定通りであり間違ってはいないように見受けられる。

何が早くなるだ。ガセネタじゃねぇか。

もう少し繰り返してみる

一度だけでは、まぁたまたま何かがあっただけかもしれないし、ということで繰り返してみた。

深さ優先

深さ優先、つまり、1つのフォルダにファイルを256個まとめて作成するようにした場合

リアル: 00:25:44.499、CPU: 00:00:42.078、GC gen0: 158, gen1: 14, gen2: 1

リアル: 00:25:27.547、CPU: 00:00:42.468、GC gen0: 159, gen1: 14, gen2: 2

リアル: 00:25:32.665、CPU: 00:00:43.703、GC gen0: 157, gen1: 13, gen2: 1

概ね25分ぐらい。

幅優先

幅優先、つまり、256個のフォルダにファイルを1個ずつ作る作業を256回繰り返すようにした場合

リアル: 00:22:58.694、CPU: 00:00:43.296、GC gen0: 158, gen1: 14, gen2: 2

リアル: 00:22:23.062、CPU: 00:00:43.859、GC gen0: 157, gen1: 14, gen2: 1

リアル: 00:23:12.904、CPU: 00:00:40.687、GC gen0: 158, gen1: 14, gen2: 2

概ね23分ぐらい。間違いなく、まとめて作るよりも早い。

とりあえず、理屈は全く分からない。


連絡先 - サイトマップ - 更新履歴
Copyright (C)  2000 - 2016 nabiki_t All Rights Reserved.