かずきのBlog

C#やJavaやRubyとメモ書き

目次

Blog 利用状況

ニュース

わんくまBlogが不安定になったため、前に書いてたはてなダイアリーにメインを移動します。
かずきのBlog@Hatena
技術的なネタは、こちらにも、はてなへのリンクという形で掲載しますが、雑多ネタははてなダイアリーだけに掲載することが多いと思います。
コメント
プログラマ的自己紹介
お気に入りのツール/IDE
プロフィール
経歴
広告
アクセサリ

書庫

日記カテゴリ

[.NET][C#]当然っちゃ当然だけどDataTableとか使いようによっては遅い

今日は、ちょっくら調べ物でした。
そこで、気づいたのがDataTableとかって便利だけど使い方によっては遅いぞと。

有名どころでは、型指定でないDataSetで、DataTableからDataRowを取得してカラムのデータにアクセスするときに文字列で列名指定すると遅めだよというのがあります。

DataRowの列データへアクセスする方法と速度

ということで、DataRowのカラムのデータにアクセスするときに文字列でアクセスするパターンとDataColumnでアクセスするパターンとインデックスで指定するパターンを試してみました。

実験コード

using System;
using System.Data;
using System.Diagnostics;
using System.Text;

namespace DataTableSpeed
{
    class Program
    {
        // 列数
        private const int COLUMN_COUNT = 30;

        // 行数
        private const int ROW_COUNT = 50000;

        static void Main(string[] args)
        {
            var dt = MakeDataTable();
            AccessColumnName(dt);
            AccessDataColumn(dt);
            AccessIndex(dt);
        }

        // テスト用データテーブルを作成する
        private static DataTable MakeDataTable()
        {
            var dt = new DataTable();
            // カラム作成
            for (int i = 0; i < COLUMN_COUNT; i++)
            {
                dt.Columns.Add("COL_" + i, typeof(string));
            }

            // 行データ追加
            for (int i = 0; i < ROW_COUNT; i++)
            {
                var row = dt.NewRow();
                foreach (DataColumn col in dt.Columns)
                {
                    row[col] = col.ColumnName + "_" + i;
                }
                dt.Rows.Add(row);
            }

            return dt;
        }

        // 列名でアクセス
        private static void AccessColumnName(DataTable dt)
        {
            var watch = new Stopwatch();
            watch.Start();
            foreach (DataRow row in dt.Rows)
            {
                var sb = new StringBuilder();
                foreach (DataColumn col in dt.Columns)
                {
                    // 文字列でアクセス!
                    sb.Append(row[col.ColumnName]);
                }
            }
            watch.Stop();
            Console.WriteLine("列名でアクセス: " + watch.ElapsedMilliseconds + "ms");
        }

        // 列名でアクセス
        private static void AccessDataColumn(DataTable dt)
        {
            var watch = new Stopwatch();
            watch.Start();
            foreach (DataRow row in dt.Rows)
            {
                var sb = new StringBuilder();
                foreach (DataColumn col in dt.Columns)
                {
                    // DataColumnでアクセス
                    sb.Append(row[col]);
                }
            }
            watch.Stop();
            Console.WriteLine("DataColumnでアクセス: " + watch.ElapsedMilliseconds + "ms");
        }

        // インデックスでアクセス
        private static void AccessIndex(DataTable dt)
        {
            var watch = new Stopwatch();
            watch.Start();
            foreach (DataRow row in dt.Rows)
            {
                var sb = new StringBuilder();
                for (int i = 0; i < COLUMN_COUNT; i++)
                {
                    // インデックスでアクセス
                    sb.Append(row[i]);
                }
            }
            watch.Stop();
            Console.WriteLine("インデックスでアクセス: " + watch.ElapsedMilliseconds + "ms");
        }
    }
}

結果
image

DataColumnとインデックスでのアクセスはまぁいいとして、列名でアクセスするときは倍くらい時間がかかってそうに見えます。
因みに型付DataSetを使うと以下のようなコードでDataRowにプロパティが定義されます。

public string Col1 {
    get {
        try {
            return ((string)(this[this.tableDataTable1.Col1Column]));
        }
        catch (global::System.InvalidCastException e) {
            throw new global::System.Data.StrongTypingException("テーブル \'DataTable1\' にある列 \'Col1\' の値は DBNull です。", e);
        }
    }
    set {
        this[this.tableDataTable1.Col1Column] = value;
    }
}

ここのthis.tableDataTable1.Col1ColumnはDataColumnなので、DataColumnを使ったアクセスをしてくれます。
性能的にも生産性的にも型付DataSetが使えるシーンでは使っておくほうが無難だと思われます。

次!!

DataTable#Rows[index]の速度

これは知らなかった。
考えりゃ当然っちゃ当然な気もするけど、DataTable#Rows[index]へのアクセスも必要最低限にするようにすると早くなります。しかも件数が多いと結構効いてくる。

実験コード

using System;
using System.Data;
using System.Diagnostics;
using System.Text;

namespace DataTableSpeed
{
    class Program
    {
        // 列数
        private const int COLUMN_COUNT = 30;

        // 行数
        private const int ROW_COUNT = 50000;

        static void Main(string[] args)
        {
            var dt = MakeDataTable();
            SlowIndexAccess(dt);
            SmartIndexAccess(dt);
            ForEachAccess(dt);
        }

        // テスト用データテーブルを作成する
        private static DataTable MakeDataTable()
        {
            var dt = new DataTable();
            // カラム作成
            for (int i = 0; i < COLUMN_COUNT; i++)
            {
                dt.Columns.Add("COL_" + i, typeof(string));
            }

            // 行データ追加
            for (int i = 0; i < ROW_COUNT; i++)
            {
                var row = dt.NewRow();
                foreach (DataColumn col in dt.Columns)
                {
                    row[col] = col.ColumnName + "_" + i;
                }
                dt.Rows.Add(row);
            }

            return dt;
        }

        // 非効率な感じ
        private static void SlowIndexAccess(DataTable dt)
        {
            var watch = new Stopwatch();
            watch.Start();
            for (int row = 0; row < ROW_COUNT; row++)
            {
                var sb = new StringBuilder();
                for (int col = 0; col < COLUMN_COUNT; col++)
                {
                    // ループ内で毎回Rowsを使ってアクセス
                    sb.Append(dt.Rows[row][col]);
                }
            }
            watch.Stop();
            Console.WriteLine("ループ内で毎回Rowsを使ってアクセス: " + watch.ElapsedMilliseconds + "ms");
        }

        // 効率的な感じ
        private static void SmartIndexAccess(DataTable dt)
        {
            var watch = new Stopwatch();
            watch.Start();
            for (int row = 0; row < ROW_COUNT; row++)
            {
                // 一度だけRowsにアクセスする
                var dataRow = dt.Rows[row];
                var sb = new StringBuilder();
                for (int col = 0; col < COLUMN_COUNT; col++)
                {
                    // daraRow変数を使いまわす
                    sb.Append(dataRow[col]);
                }
            }
            watch.Stop();
            Console.WriteLine("必要最低限のRowsへのアクセス: " + watch.ElapsedMilliseconds + "ms");
        }

        // まかせる
        private static void ForEachAccess(DataTable dt)
        {
            var watch = new Stopwatch();
            watch.Start();
            // foreachによるアクセス
            foreach (DataRow dataRow in dt.Rows)
            {
                var sb = new StringBuilder();
                for (int col = 0; col < COLUMN_COUNT; col++)
                {
                    // daraRow変数を使いまわす
                    sb.Append(dataRow[col]);
                }
            }
            watch.Stop();
            Console.WriteLine("foreachでアクセス: " + watch.ElapsedMilliseconds + "ms");
        }

    }
}

実行結果
image

Selectメソッドによる検索

これは当然。汎用的なメソッド程遅いのが道理。
どれくらい違うのか試してみました。

実験コード

using System;
using System.Data;
using System.Diagnostics;
using System.Text;
using System.Linq;
using System.Collections.Generic;

namespace DataTableSpeed
{
    class Program
    {
        // 列数
        private const int COLUMN_COUNT = 30;

        // 行数
        private const int ROW_COUNT = 50000;

        static void Main(string[] args)
        {
            var dt = MakeDataTable();
            UseSelect(dt);
            UseLinq(dt);
            UseLoop(dt);
        }

        // テスト用データテーブルを作成する
        private static DataTable MakeDataTable()
        {
            var dt = new DataTable();
            // カラム作成
            for (int i = 0; i < COLUMN_COUNT; i++)
            {
                dt.Columns.Add("COL_" + i, typeof(string));
            }

            // 行データ追加
            for (int i = 0; i < ROW_COUNT; i++)
            {
                var row = dt.NewRow();
                foreach (DataColumn col in dt.Columns)
                {
                    row[col] = col.ColumnName + "_" + i;
                }
                dt.Rows.Add(row);
            }

            return dt;
        }

        private static void UseSelect(DataTable dt)
        {
            var watch = new Stopwatch();
            watch.Start();
            // COL_1の値がCOL_1_10000の列が欲しいねん
            var ret = dt.Select("COL_1 = 'COL_1_10000'");
            watch.Stop();

            Console.WriteLine("Selectで検索: " + watch.ElapsedMilliseconds + "ms");
        }

        private static void UseLinq(DataTable dt)
        {
            var watch = new Stopwatch();
            watch.Start();
            // COL_1の値がCOL_1_10000の列が欲しいねん
            var col1 = dt.Columns["COL_1"];
            var ret = dt.AsEnumerable().Where(row => (string)row[col1] == "COL_1_10000").ToArray();
            watch.Stop();

            Console.WriteLine("Linqで検索: " + watch.ElapsedMilliseconds + "ms");
        }

        private static void UseLoop(DataTable dt)
        {
            var watch = new Stopwatch();
            watch.Start();
            // COL_1の値がCOL_1_10000の列が欲しいねん
            var col1 = dt.Columns["COL_1"];
            var list = new List<DataRow>();
            foreach (DataRow row in dt.Rows)
            {
                if ((string)row[col1] == "COL_1_10000")
                {
                    list.Add(row);
                }
            }
            var ret = list.ToArray();
            watch.Stop();

            Console.WriteLine("ループで検索: " + watch.ElapsedMilliseconds + "ms");
        }

    }
}

実行結果
image

ということで、Selectがダントツで遅いです。
いっぱつ限りならいいですが、ループ内でSelectを使って検索を繰り返すときはLinqかループでごりっとやっちゃいましょう。

 

ということを今日体感しました。

投稿日時 : 2009年6月25日 22:58

Feedback

# re: [.NET][C#]当然っちゃ当然だけどDataTableとか使いようによっては遅い 2009/06/26 11:06 aetos

> 列名でアクセスするときは倍くらい時間がかかってそうに見えます

列名から DataColumn を探すのにかかる時間が、もとから DataColumn を使う場合に上乗せされるからでしょうかね。

> 性能的にも生産性的にも型付DataSetが使えるシーンでは使っておくほうが無難だと思われます。

しかし何故か DataColumn を internal メンバにしてくれるので、アセンブリをまたいで使うような DataSet では列名を使わざるを得なかったり。

> ということで、Selectがダントツで遅いです。

DataView.Find との速度比較も欲しいなーと思ったり。
先日、仕事で書いてプログラムで、DataView を new するコストが馬鹿にならなかったことがありましたが。

# re: [.NET][C#]当然っちゃ当然だけどDataTableとか使いようによっては遅い 2009/06/26 11:09 aetos

ああ勘違い。
列プロパティを使えるところでは使えってことですね。

ところで、.NET 2.0 からは、Nullable 型になったりしてるんでしょうか?
でないと、NULL が入り得て、妥当な NullValue も設定できない列では、列名アクセスせざるを得ないので…

# [.NET][C#]当然っちゃ当然だけどDataTableとか使いようによっては遅い その2 2009/09/23 1:05 かずきのBlog

[.NET][C#]当然っちゃ当然だけどDataTableとか使いようによっては遅い その2

# [.NET][C#]DataTableからのデータ抽出方法の性能比較 2009/12/17 22:34 かずきのBlog

[.NET][C#]DataTableからのデータ抽出方法の性能比較

# re: [.NET][C#]当然っちゃ当然だけどDataTableとか使いようによっては遅い 2009/12/17 23:14 ひらぽん

ADO.NET 専修講座(VB.NET編) という本にこの辺の話が載ってましたので、6月頃試してみたことがあります。
で、実験結果↓

http://blogs.yahoo.co.jp/hilapon/2573935.html

DataColumn の事前バインディングが最も速かったです。

# re: [.NET][C#]当然っちゃ当然だけどDataTableとか使いようによっては遅い 2010/11/26 20:04 u0zzub8oboubr4897 zz zzihioglirs.bn

7894561230
789456130
7894561230
789945611230

# welded ball valve 2012/10/18 22:31 http://www.jonloovalve.com/Full-welded-ball-valve-

Absolutely composed subject material , regards for entropy.

# burberry outlet sale 2012/10/26 2:54 http://www.burberryoutletscarfsale.com

Only a smiling visitant here to share the love (:, btw outstanding pattern .
burberry outlet sale http://www.burberryoutletscarfsale.com

# mens shirts 2012/10/26 2:54 http://www.burberryoutletscarfsale.com/burberry-me

obviously like your website but you have to test the spelling on quite a few of your posts. A number of them are rife with spelling issues and I in finding it very bothersome to inform the reality on the other hand I will definitely come back again.
mens shirts http://www.burberryoutletscarfsale.com/burberry-men-shirts.html

# cheap tie 2012/10/26 2:55 http://www.burberryoutletscarfsale.com/accessories

I like this post, enjoyed this one thankyou for posting .
cheap tie http://www.burberryoutletscarfsale.com/accessories/burberry-ties.html

# t shirt scarf 2012/10/26 2:55 http://www.burberryoutletscarfsale.com/accessories

certainly like your web-site but you have to test the spelling on several of your posts. Many of them are rife with spelling issues and I to find it very bothersome to tell the truth then again I'll certainly come back again.
t shirt scarf http://www.burberryoutletscarfsale.com/accessories/burberry-scarf.html

# burberry womens shirts 2012/10/26 2:55 http://www.burberryoutletscarfsale.com/burberry-wo

I like this website so much, saved to bookmarks. "Respect for the fragility and importance of an individual life is still the mark of an educated man." by Norman Cousins.
burberry womens shirts http://www.burberryoutletscarfsale.com/burberry-womens-shirts.html

# burberry watches on sale 2012/10/28 14:44 http://www.burberryoutletscarfsale.com/accessories

Only wanna comment on few general things, The website design and style is perfect, the content is really excellent : D.
burberry watches on sale http://www.burberryoutletscarfsale.com/accessories/burberry-watches.html

# mens shirts 2012/11/01 3:49 http://www.burberryoutletlocations.com/burberry-me

Great write-up, I am regular visitor of one's site, maintain up the excellent operate, and It is going to be a regular visitor for a lengthy time.
mens shirts http://www.burberryoutletlocations.com/burberry-men-shirts.html

# cheap burberry bags 2012/11/01 3:50 http://www.burberryoutletlocations.com/burberry-wo

of course like your web site but you need to test the spelling on quite a few of your posts. Many of them are rife with spelling issues and I to find it very bothersome to inform the reality however I will surely come again again.
cheap burberry bags http://www.burberryoutletlocations.com/burberry-women-bags.html

# wallet 2012/11/01 3:50 http://www.burberryoutletlocations.com/burberry-wa

Hello, Neat post. There's an issue along with your website in internet explorer, would check this… IE still is the market leader and a big element of people will omit your great writing because of this problem.
wallet http://www.burberryoutletlocations.com/burberry-wallets-2012.html

# t shirts 2012/11/01 3:50 http://www.burberryoutletlocations.com/burberry-wo

I like this post, enjoyed this one regards for putting up. "Pain is inevitable. Suffering is optional." by M. Kathleen Casey.
t shirts http://www.burberryoutletlocations.com/burberry-womens-shirts.html

# wallet 2012/11/02 22:29 http://www.burberryoutletscarfsale.com/accessories

obviously like your website however you have to take a look at the spelling on quite a few of your posts. Several of them are rife with spelling problems and I find it very bothersome to tell the reality on the other hand I will definitely come again again.
wallet http://www.burberryoutletscarfsale.com/accessories/burberry-wallets-2012.html

# burberry bags 2012/11/02 22:29 http://www.burberryoutletscarfsale.com/burberry-ba

I was examining some of your blog posts on this site and I think this internet site is rattling instructive! Retain putting up.
burberry bags http://www.burberryoutletscarfsale.com/burberry-bags.html

# Adidas Climacool Ride 2012/11/03 2:17 http://www.adidasoutle.com/adidas-shoes-adidas-cli

Thanks for the sensible critique. Me & my neighbor were just preparing to do a little research about this. We got a grab a book from our area library but I think I learned more clear from this post. I'm very glad to see such excellent info being shared freely out there.
Adidas Climacool Ride http://www.adidasoutle.com/adidas-shoes-adidas-climacool-ride-c-1_3.html

# burberry scarf 2012/11/03 10:58 http://www.burberryoutletlocations.com/burberry-sc

Some genuinely fantastic information, Glad I found this. "If you haven't forgiven yourself something, how can you forgive others" by Dolores Huerta.
burberry scarf http://www.burberryoutletlocations.com/burberry-scarf.html

# burberry watches for women 2012/11/03 10:58 http://www.burberryoutletlocations.com/burberry-wa

You are my inspiration , I possess few web logs and very sporadically run out from to brand.
burberry watches for women http://www.burberryoutletlocations.com/burberry-watches.html

# Canada goose online 2012/11/14 22:45 http://www.goosefromcanada.com/

I really like your writing style, wonderful info, regards for putting up :D. "If a cluttered desk is the sign of a cluttered mind, what is the significance of a clean desk" by Laurence J. Peter.
Canada goose online http://www.goosefromcanada.com/

# supra high top shoes 2012/11/16 12:13 http://www.suprafashionshoes.com

http://www.suprafashionshoes.comsupra high top shoes
supra high top shoes http://www.suprafashionshoes.com

# make money writing articles online 2012/11/17 0:12 http://www.makemoneyday.info/category/make-money-w

I was studying some of your content on this website and I conceive this web site is really instructive! Keep on putting up.
make money writing articles online http://www.makemoneyday.info/category/make-money-writing-articles/

# nike free 2012/11/19 1:08 http://www.nikefreerunherrenfrauen.com/

Dead indited content material, appreciate it for selective information. "The bravest thing you can do when you are not brave is to profess courage and act accordingly." by Corra Harris.
nike free http://www.nikefreerunherrenfrauen.com/

# Nike Air Max 95 Womens 2012/11/19 11:55 http://www.superairmaxshoes.com/nike-air-max-95-wo

Only a smiling visitor here to share the love (:, btw great layout. "Individuals may form communities, but it is institutions alone that can create a nation." by Benjamin Disraeli.
Nike Air Max 95 Womens http://www.superairmaxshoes.com/nike-air-max-95-womens-c-23.html

# Nike Air Max 2012 Mens 2012/11/19 11:55 http://www.superairmaxshoes.com/nike-air-max-2012-

I like this post, enjoyed this one regards for putting up. "No man is wise enough by himself." by Titus Maccius Plautus.
Nike Air Max 2012 Mens http://www.superairmaxshoes.com/nike-air-max-2012-mens-c-7.html

# Women Moncler Jackets 2012/11/19 19:54 http://www.supermonclercoats.com/women-moncler-jac

Rattling great information can be found on weblog . "The fundamental defect of fathers is that they want their children to be a credit to them." by Bertrand Russell.
Women Moncler Jackets http://www.supermonclercoats.com/women-moncler-jackets-c-4.html

# moncler online 2012/11/21 21:21 http://www.monclercoatonline.com.es

I was examining some of your content on this internet site and I think this web site is very instructive! Retain posting.
moncler online http://www.monclercoatonline.com.es

# chaquetas moncler mujer 2012/11/21 21:22 http://www.monclercoatonline.com.es/chaquetas-monc

Simply wanna comment that you have a very decent internet site , I like the pattern it actually stands out.
chaquetas moncler mujer http://www.monclercoatonline.com.es/chaquetas-moncler-mujeres-c-4.html

# www.bagsamazon.info 2012/11/21 22:54 http://www.bagsamazon.info/

Rattling good information can be found on blog . "Time discovers truth." by Lucius Annaeus Seneca.
www.bagsamazon.info http://www.bagsamazon.info/

# www.cameraamazon.info 2012/11/21 22:54 http://www.cameraamazon.info/

of course like your web site however you have to check the spelling on quite a few of your posts. Many of them are rife with spelling issues and I in finding it very bothersome to inform the truth then again I'll certainly come back again.
www.cameraamazon.info http://www.cameraamazon.info/

# cheap air jordan shoes 2012/11/22 13:56 http://www.suparjordanshoes.com

I really appreciate this post. I've been looking all over for this! Thank goodness I found it on Bing. You have made my day! Thanks again!
cheap air jordan shoes http://www.suparjordanshoes.com

# air jordan 5 retro 2012/11/22 13:56 http://www.suparjordanshoes.com/air-jordan-5-retro

It is truly a great and helpful piece of info. I am satisfied that you just shared this helpful info with us. Please keep us informed like this. Thanks for sharing.
air jordan 5 retro http://www.suparjordanshoes.com/air-jordan-5-retro-c-21.html

# supra tk society 2012/11/22 14:54 http://www.supratkstore.com

Some really choice content on this website , saved to bookmarks .
supra tk society http://www.supratkstore.com

# Christian Louboutin 2012 2012/11/22 18:02 http://www.mychristianlouboutinonline.com/christia

Dead pent articles, Really enjoyed reading.
Christian Louboutin 2012 http://www.mychristianlouboutinonline.com/christian-louboutin-2012-c-1.html

# Christian Louboutin Daffodil 2012/11/22 18:02 http://www.mychristianlouboutinonline.com/christia

Appreciate it for helping out, excellent info. "The surest way to be deceived is to think oneself cleverer than the others." by La Rochefoucauld.
Christian Louboutin Daffodil http://www.mychristianlouboutinonline.com/christian-louboutin-daffodil-c-5.html

# oZspmODAVvfXjE 2014/08/06 22:57 http://crorkz.com/

Ok19GL Thanks so much for the blog post.Much thanks again. Fantastic.

# nYlttkmHuoxdVZpj 2014/09/02 19:15 http://www.botaniquebartley.info/

Greetings! I've been reading your website for some time now and finally got the courage to go ahead and give you a shout out from Houston Texas! Just wanted to mention keep up the fantastic work!

# cEOyusBetpGDS 2014/09/09 9:51 http://vender-por-internet.net/luis-souto/

I am typically to blogging and i really recognize your content. The article has actually peaks my interest. I am going to bookmark your website and hold checking for new information.

# opaspRIGIh 2014/09/09 11:25 http://vender-na-internet.com/luis-souto/

you will have a fantastic blog right here! would you prefer to make some invite posts on my weblog?

# WyCWFYOzADDQ 2014/09/12 20:20 http://www.youtube.com/watch?v=6eoaR-4GvzQ

Hi there, You've done an incredible job. I'll certainly digg it and personally recommend to my friends. I'm sure they will be benefited from this site.

# Evqnb Bkg Opki Kpj Dxscfg 2014/12/13 16:55 DonaldDuS

http://www.beinoperfume.com/gas/20141211225150132.htmhttp://www.ch-distributing.com/gas/20141211225150949.htm http://www.jhcranch.com/sasas/201412121121235846.htmhttp://www.poranch.net/sasas/201412121121225975.htm http://www.jamesbuckey.com/sandy/201412121136465290.htmhttp://www.rivaarmy.com/sandy/201412121136458080.htm
http://www.buotta.com/gas/20141211225150072.htmhttp://www.barrettinstitute.com/gas/20141211225150785.htm http://www.manoy.com/sasas/201412121121222376.htmhttp://www.networktherapists.com/sasas/201412121121233423.htm http://www.firstmastersimo.com/sandy/201412121136465810.htmhttp://www.rivergatecondos.com/sandy/201412121136460921.htm
http://www.cammond.com/gas/20141211225151803.htmcontains by simply being foot very hot and also sofa to make sure you actually casual sprint sock. The latest meteor shower contains phenomenoms of sunshine http://www.cheonian.com/gas/20141211225151809.htmeliminates. Low cost Lovely handbag Becky, I would like you to definitely find Imari TMs organize in the office and bring about this approach affair so that you could she prolonged filehttp://www.burtonanddavis.com/gas/20141211225151047.htm. Within the Hermes Kelly felix motorola motorola clutch styles, there exists a Kelly felix small pochette clutch system being concerning the nearly all variationshttp://www.ewaidsynod.org/sasas/201412121121222030.htm. If the main loved one is managing after a sector that offers coverage of health14909, which is probably the most effective package you will get, Matheis claimshttp://www.nn4zz.com/sasas/201412121121222130.htm. Attempt in top rate, by doing this great it does not exclusively 'real. 'Critics unsurprisingly ignore which usually we have been handling generally a powerful a new wonderland stuffhttp://www.truenorthsamon.com/sandy/201412121136462877.htm, specially the significantly more outstanding components of gadget. Always make sure to want to not forget for all times when you may be operating where you go along thehttp://www.eformz.com/sandy/201412121136480398.htm

# The T-shirt is so stylish and fashionable. Its material is so good. But I love the dog in front of this shirt and I bought it. What's about you? 2016/11/19 9:45 JasonCrafe

The T-shirt is so stylish and fashionable. Its material is so good. But I love the dog in front of this shirt and I bought it. What's about you?
Click for info:

http://bit.ly/Dogstee

Thx

タイトル  
名前  
Url
コメント