気まぐれ小技集

ブログ始めました! ホームページ http://www.sunshinesystem.co.jp

全体表示

[ リスト | 詳細 ]

記事検索
検索

全3ページ

[1] [2] [3]

[ 次のページ ]

DirectCastとCType

型変換でCTypeよりDirectCastの方が高速という事はよく聞くのですが、実際どのようになっているのかは理解していなかったので、検証も含め調査しました。

Shared Sub Main()

Dim a As Object = 0
Dim b As Object = 0

Dim c As Double = DirectCast(a, Integer)
Dim d As Double = CType(b, Integer)

End Sub

をビルドしたexeをildasmでILコードに逆アセンブルします。

.method public static void Main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// コード サイズ 38 (0x26)
.maxstack 1
.locals init ([0] object a,
[1] object b,
[2] float64 c,
[3] float64 d)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: box [mscorlib]System.Int32
IL_0007: stloc.0
IL_0008: ldc.i4.0
IL_0009: box [mscorlib]System.Int32
IL_000e: stloc.1
IL_000f: ldloc.0
IL_0010: unbox [mscorlib]System.Int32
IL_0015: ldobj [mscorlib]System.Int32
IL_001a: conv.r8
IL_001b: stloc.2
IL_001c: ldloc.1
IL_001d: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Conversions::ToInteger(object)
IL_0022: conv.r8
IL_0023: stloc.3
IL_0024: nop
IL_0025: ret
} // end of method Class1::Main

DirectCastの方は.NET Frameworkの[unbox]を使用しているのに対し、CTypeはMicrosoft.VisualBasic.CompilerServices.ConversionsのToInteger関数をコールしている事が解ります。
MSDNによるとDirectCast使用時はVisual Basic のランタイム ヘルパー ルーチン(上記)を変換に使用しない為、高速なのだそうです。

For i As Integer = 0 To 99999999
Dim a As Object = 0
Dim c As Double = CType(a, Integer) ' or DirectCast
Next

で試したところ、DirectCastの場合は約1秒、CTypeの場合は約2.5秒かかりました。
特に制約がない場合は、DirectCastを使用したほうがやはり高速なようです。
注意点に関しては
http://msdn.microsoft.com/ja-jp/library/7k6y2h6x(v=vs.80).aspx
を参照してください。

閉じる コメント(0) ※投稿されたコメントはブログ開設者の承認後に公開されます。

閉じる トラックバック(0) ※トラックバックはブログ開設者の承認後に公開されます。

覚書

厳密型指定されたDatatableの場合
[Datatable].Item([RowIndex])
で指定行が取得できる&プロパティ経由で列値が取得できるようになる。

[Datatable].Rows([RowIndex]).Item([ColumnName])
で取得した場合は、デザイナで列に設定した設定値は反映されないような気がする。
(プロパティ経由でないから?要検証)

キーを設定していないデータテーブルへの値代入はやたらと遅い。
キーをいったん外し、再設定した場合TableAdapterを使用したUpdateがやたらと遅い。
TransactionScope&TableAdapterを使用した更新は、Connectionが複数存在した場合分散トランザクションに昇格してしまうので、気をつけること。

閉じる コメント(0) ※投稿されたコメントはブログ開設者の承認後に公開されます。

閉じる トラックバック(0)

mvc conf

みなさんこんばんは。スパムが多いのでWORDPRESSに移行しようかと思っているSです。
昨日、USTREAMで@ITさんとMicrosoft Tech Fieldersさん主催のmvcConf @:Japanを見ていたのですが、以前から気になっていた
mvc、Razor、コードファースト、Azureの色々な話が聞けて、とても為になりました。
実業務で使用することは当面ないと思うのですが、少しづつ勉強していこうと思います。
なお、今回のセミナーは後日Channel9でも公開されるそうなので、興味のある方は見てみてください。

channel9 http://channel9.msdn.com/tags/japan/
当日使用されたスライド http://www.slideshare.net/mvcjpn/

閉じる コメント(0) ※投稿されたコメントはブログ開設者の承認後に公開されます。

閉じる トラックバック(0)

TableAdapterのConnection設定

データセットデザイナで作成したTableAdapterの各コマンドを使用する時、Conectionプロパティを指定しない場合、デザイナで作成時に設定したコネクションを自動でオープンしてしまいます。
コネクションを意識する必要が無いので便利なのですが、既に別コネクションが開かれている場合でも別のコネクションを開いてしまいます。
.Connectionプロパティに現在使用しているコネクションを設定すれば、新たにコネクションを開くことなく指定したコネクションを使用するようになります。内部的に保持しているSELECT、UPDATE、INSERT、DELETEにも反映されます。

例)
        Using con As New SqlClient.SqlConnection(My.Settings.CDRentalConnectionString)

            con.Open()

            Dim dt As DataSet1.M_CDDataTable = Nothing
            Using adapter As New DataSet1TableAdapters.M_CDTableAdapter

                ' この設定がないと自動的にコネクションをOpenする為、2接続状態になってしまう!
                adapter.Connection = con

                dt = adapter.GetData
                adapter.Update(dt)
            End Using

        End Using

閉じる コメント(0)

閉じる トラックバック(0)

歯抜けの最小番号を取得

-- 歯抜けの最小値を探す
SELECT MIN(seq + 1) AS gap
FROM SeqTbl
WHERE (seq+ 1) NOT IN ( SELECT seq FROM SeqTbl);

という風に書けば探索できます。(元の数値 + 1 がテーブルに存在していないもの = 歯抜け の最小値を取ってきている。)
但し、トラックバック先でも言及されているようにテーブルのデータ量が多ければ多いほどコストが増大してしまうので、大量のデータが入る可能性のあるテーブルはコーディングしたほうがよさそうです。
検証は後日行おうと思います。-- 歯抜けの最小値を探す
SELECT MIN(seq + 1) AS gap
FROM SeqTbl
WHERE (seq+ 1) NOT IN ( SELECT seq FROM SeqTbl);

という風に書けば探索できます。(元の数値 + 1 がテーブルに存在していないもの = 歯抜け の最小値を取ってきている。)
但し、トラックバック先でも言及されているようにテーブルのデータ量が多ければ多いほどコストが増大してしまうので、大量のデータが入る可能性のあるテーブルはコーディングしたほうがよさそうです。
検証は後日行おうと思います。

2011/05/21
検証マシンスペック CORE i5 2.4GHz
数万件位のデータの場合、1秒以内で返ってきましたが、2000万件のデータでは結果が返ってくるまでに14秒位かかりました。
この方法だと空き番の離れ具合は関係ないので、データ件数が増えない限りかかる時間は変わらないです。
それと、この方法だと最小番号を元に空き番を探すため、最小以前の番号が採番号出来ませんので、厳密に採番する場合は使用しない方が良いです。
(検証中にVSが落ちてしまい、プロジェクトを保存していなかったので再検証が出来ない状態です。。)
コード上で1づつカウントアップしてDBに存在確認をしながら探す方法は、100万件位次の番号と離れている場合は秒単位の問題でないくらい時間がかかるのでお勧めできません。
Readerでデータを回しながらカウントアップしていき、相違が出た時点のカウントを空き番とする方法なら100万件位次の番号と離れている場合でも3秒以内で割り出せたので、現時点ではこの方法が一番良いような気がします。
(最終存在確認はした方が良いと思います。)

列番 | キー値 | カウント
1 | 4 | 4
2 | 5 | 5
3 | 6 | 6
4 | 8 | 7 ←この時点でキー値 <> カウントなので
5 | 9 | 最近の空き番は「7」

直接は関係ないのですが、SQLSERVERの場合はキー列にIDENTITY属性を設定しておけば自動で採番してくれます。

閉じる コメント(0) ※投稿されたコメントはブログ開設者の承認後に公開されます。

閉じる トラックバック(0)

全3ページ

[1] [2] [3]

[ 次のページ ]


.

sunshinesystem
人気度

ヘルプ

Yahoo Image

  今日 全体
訪問者 4 2293
ブログリンク 0 0
コメント 0 11
トラックバック 0 0

ケータイで見る

モバイル版Yahoo!ブログにアクセス!

モバイル版Yahoo!ブログにアクセス!

URLをケータイに送信
(Yahoo! JAPAN IDでのログインが必要です)

1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

標準グループ

登録されていません

開設日: 2010/2/5(金)


プライバシーポリシー -  利用規約 -  ガイドライン -  順守事項 -  ヘルプ・お問い合わせ

Copyright (C) 2012 Yahoo Japan Corporation. All Rights Reserved.