C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

全過去ログを検索

<< 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 >>
■82448  Re[34]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ -(2017/01/10(Tue) 21:58:47)
    以下が改良したコードです。

    Namespace Force_Crc32
    Friend Class SafeProxy
    Private Const Poly As UInteger = &HEDB88320UI

    Private Shared ReadOnly _table As UInteger() = New UInteger(16 * 256 - 1) {}

    Shared Sub New()
    For i As UInteger = 0 To 255
    Dim res As UInteger = i
    For t As Integer = 0 To 15
    For k As Integer = 0 To 7
    res = If((res And 1) = 1, Poly Xor (res >> 1), (res >> 1))
    Next
    _table((t * 256) + i) = res
    Next
    Next
    End Sub

    Public Function Append(ByVal crc As UInteger, ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger
    Dim crcLocal As UInteger = UInteger.MaxValue Xor crc

    Dim table As UInteger() = _table
    While length >= 16
    crcLocal = table((15 * 256) + ((crcLocal Xor input(offset)) And &HFF)) _
    Xor table((14 * 256) + (((crcLocal >> 8) Xor input(offset + 1)) And &HFF)) _
    Xor table((13 * 256) + (((crcLocal >> 16) Xor input(offset + 2)) And &HFF)) _
    Xor table((12 * 256) + (((crcLocal >> 24) Xor input(offset + 3)) And &HFF)) _
    Xor table((11 * 256) + input(offset + 4)) _
    Xor table((10 * 256) + input(offset + 5)) _
    Xor table((9 * 256) + input(offset + 6)) _
    Xor table((8 * 256) + input(offset + 7)) _
    Xor table((7 * 256) + input(offset + 8)) _
    Xor table((6 * 256) + input(offset + 9)) _
    Xor table((5 * 256) + input(offset + 10)) _
    Xor table((4 * 256) + input(offset + 11)) _
    Xor table((3 * 256) + input(offset + 12)) _
    Xor table((2 * 256) + input(offset + 13)) _
    Xor table((1 * 256) + input(offset + 14)) _
    Xor table((0 * 256) + input(offset + 15))
    offset += 16
    length -= 16
    End While

    'While System.Threading.Interlocked.Decrement(length) >= 0
    While length >= 0
    length -= 1
    'crcLocal = table((crcLocal Xor input(System.Math.Max(System.Threading.Interlocked.Increment(offset), offset - 1))) And &HFF) Xor crcLocal >> 8
    offset += 1
    crcLocal = table((crcLocal Xor input(offset)) And &HFF) Xor crcLocal >> 8
    End While
    Return crcLocal Xor UInteger.MaxValue
    End Function
    End Class
    End Namespace




    Imports System
    Imports System.Security.Cryptography

    Namespace Force_Crc32
    ''' <summary>
    ''' Implementation of CRC-32.
    ''' This class supports several convenient static methods returning the CRC as UInt32.
    ''' </summary>
    Public Class Crc32Algorithm
    Inherits HashAlgorithm
    Private _currentCrc As UInteger

    ''' <summary>
    ''' Initializes a new instance of the <see cref="Crc32Algorithm"/> class.
    ''' </summary>
    Public Sub New()
    #If Not NETCORE Then
    HashSizeValue = 32
    #End If
    End Sub


    ''' <summary>
    ''' Computes CRC-32 from multiple buffers.
    ''' Call this method multiple times to chain multiple buffers.
    ''' </summary>
    ''' <param name="initial">
    ''' Initial CRC value for the algorithm. It is zero for the first buffer.
    ''' Subsequent buffers should have their initial value set to CRC value returned by previous call to this method.
    ''' </param>
    ''' <param name="input">Input buffer with data to be checksummed.</param>
    ''' <param name="offset">Offset of the input data within the buffer.</param>
    ''' <param name="length">Length of the input data in the buffer.</param>
    ''' <returns>Accumulated CRC-32 of all buffers processed so far.</returns>
    Public Shared Function Append(ByVal initial As UInteger, ByVal input2 As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger
    If input2 Is Nothing Then
    Throw New ArgumentNullException()
    End If
    If offset < 0 OrElse length < 0 OrElse offset + length > input2.Length Then
    Throw New ArgumentOutOfRangeException("Selected range is outside the bounds of the input array")
    End If
    Return AppendInternal(initial, input2, offset, length)
    End Function

    ''' <summary>
    ''' Computes CRC-3C from multiple buffers.
    ''' Call this method multiple times to chain multiple buffers.
    ''' </summary>
    ''' <param name="initial">
    ''' Initial CRC value for the algorithm. It is zero for the first buffer.
    ''' Subsequent buffers should have their initial value set to CRC value returned by previous call to this method.
    ''' </param>
    ''' <param name="input">Input buffer containing data to be checksummed.</param>
    ''' <returns>Accumulated CRC-32 of all buffers processed so far.</returns>
    Public Shared Function Append(ByVal initial As UInteger, ByVal input As Byte()) As UInteger
    If input Is Nothing Then
    Throw New ArgumentNullException()
    End If
    Return AppendInternal(initial, input, 0, input.Length)
    End Function

    ''' <summary>
    ''' Computes CRC-32 from input buffer.
    ''' </summary>
    ''' <param name="input">Input buffer with data to be checksummed.</param>
    ''' <param name="offset">Offset of the input data within the buffer.</param>
    ''' <param name="length">Length of the input data in the buffer.</param>
    ''' <returns>CRC-32 of the data in the buffer.</returns>
    Public Shared Function Compute(ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger
    Return Append(0, input, offset, length)
    End Function

    ''' <summary>
    ''' Computes CRC-32 from input buffer.
    ''' </summary>
    ''' <param name="input">Input buffer containing data to be checksummed.</param>
    ''' <returns>CRC-32 of the buffer.</returns>
    Public Shared Function Compute(ByVal input As Byte()) As UInteger
    Return Append(0, input)
    End Function

    ''' <summary>
    ''' Resets internal state of the algorithm. Used internally.
    ''' </summary>
    Public Overrides Sub Initialize()
    _currentCrc = 0
    End Sub

    ''' <summary>
    ''' Appends CRC-32 from given buffer
    ''' </summary>
    Protected Overrides Sub HashCore(ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer)
    _currentCrc = AppendInternal(_currentCrc, input, offset, length)
    End Sub

    ''' <summary>
    ''' Computes CRC-32 from <see cref="HashCore"/>
    ''' </summary>
    Protected Overrides Function HashFinal() As Byte()
    ' Crc32 by dariogriffo uses big endian, so, we need to be compatible and return big endian too
    Return New Byte() {CByte(_currentCrc >> 24 And &HFF), CByte(_currentCrc >> 16 And &HFF), CByte(_currentCrc >> 8 And &HFF), CByte(_currentCrc And &HFF)}
    End Function

    Private Shared ReadOnly _proxy As New SafeProxy()

    Private Shared Function AppendInternal(ByVal initial As UInteger, ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger
    If length > 0 Then
    Return _proxy.Append(initial, input, offset, length)
    Else
    Return initial
    End If
    End Function
    End Class
    End Namespace
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82449  Re[35]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/10(Tue) 22:14:54)
    No82448 (ぎゅんぎゅ さん) に返信
    > 以下が改良したコードです。
    > 'While System.Threading.Interlocked.Decrement(length) >= 0
    > While length >= 0
    > length -= 1
    > 'crcLocal = table((crcLocal Xor input(System.Math.Max(System.Threading.Interlocked.Increment(offset), offset - 1))) And &HFF) Xor crcLocal >> 8
    > offset += 1
    > crcLocal = table((crcLocal Xor input(offset)) And &HFF) Xor crcLocal >> 8
    > End While

    とりあえず

    > While length >= 0


    While length > 0
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82450  Re[36]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/10(Tue) 22:24:36)
    No82449 (なちゃ さん) に返信
    > ■No82448 (ぎゅんぎゅ さん) に返信
    >>以下が改良したコードです。
    >> 'While System.Threading.Interlocked.Decrement(length) >= 0
    >> While length >= 0
    >> length -= 1
    >> 'crcLocal = table((crcLocal Xor input(System.Math.Max(System.Threading.Interlocked.Increment(offset), offset - 1))) And &HFF) Xor crcLocal >> 8
    >> offset += 1
    >> crcLocal = table((crcLocal Xor input(offset)) And &HFF) Xor crcLocal >> 8
    >> End While

    これも逆順ですね。

    >> offset += 1
    >> crcLocal = table((crcLocal Xor input(offset)) And &HFF) Xor crcLocal >> 8

    crcLocal = table((crcLocal Xor input(offset)) And &HFF) Xor crcLocal >> 8
    offset += 1
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82451  Re[37]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ -(2017/01/10(Tue) 22:31:35)
    なちゃ さん

    ありがとうございます。

    うまくいきました
    同じ結果が得られました

    しかもC#のDLLを使うよりも30%くらい速くなりました
    前に同じコードをVBとC#で比較して
    1.5〜2倍くらいC#の方が常に速い結果が得られていたのですが
    DLLで読み込ませるとそうならないようですね

    もう少しいろいろ試してみます。
     
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82453  Re[38]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ -(2017/01/10(Tue) 22:37:53)
    間違いました

    C# DLLの方が30%くらい速いです。

    やはり計算量の多いコードはVBで書かずに
    C#かC++で書いてDLL化した方が良いということでしょうか
     
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82455  Re[39]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/10(Tue) 22:41:14)
    No82453 (ぎゅんぎゅ さん) に返信
    > 間違いました
    >
    > C# DLLの方が30%くらい速いです。
    >
    > やはり計算量の多いコードはVBで書かずに
    > C#かC++で書いてDLL化した方が良いということでしょうか
    >  

    VBはオーバーフローチェックとか省けなかったりするので、余計な処理が入る可能性が高いです。
    C#はましですが、C++よりは余計な処理が入るでしょう。

    ちなみに実行速度は、以前のと比べた場合はどんな感じですか?
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82458  Re[40]: VBでCRC32を高速で計算する方法
□投稿者/ 魔界の仮面弁士 -(2017/01/10(Tue) 23:50:06)
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82459  Re[41]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/11(Wed) 00:07:20)
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82452  Re[38]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/10(Tue) 22:35:22)
    No82451 (ぎゅんぎゅ さん) に返信
    > なちゃ さん
    >
    > ありがとうございます。
    >
    > うまくいきました
    > 同じ結果が得られました
    >
    > しかもC#のDLLを使うよりも30%くらい速くなりました
    > 前に同じコードをVBとC#で比較して
    > 1.5〜2倍くらいC#の方が常に速い結果が得られていたのですが
    > DLLで読み込ませるとそうならないようですね
    >
    > もう少しいろいろ試してみます。
    >  

    なんかその辺はどうも怪しいですけどね。
    実はDebugビルドになってたとかないですか?
    こちらはC#の方がやや速かったですが。
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82454  Re[39]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/10(Tue) 22:38:20)
    No82452 (なちゃ さん) に返信
    > なんかその辺はどうも怪しいですけどね。
    > 実はDebugビルドになってたとかないですか?
    > こちらはC#の方がやや速かったですが。

    よく見るとこのライブラリstaticコンストラクタ使ってるので、細かくは見ていませんが、
    場合によってはパフォーマンスに影響してるかもしれないですね。
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82456  Re[40]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ -(2017/01/10(Tue) 22:48:13)
    500MBを処理するのに


    VBの旧CRC(integer) 4.0sec
    VBの旧CRC(uinteger) 1.45sec
    VBのMD5 1.2sec

    VBの新CRC 0.84sec
    C#DLL 0.59sec

    でした。

    劇的に速くなっています。

    ところでこれってどういうアルゴリズムを使っているのでしょうか?
    データ読込と計算を並列化しているのでしょうか?
    コードを見れば分かると思ったのですが
    見てもさっぱり何の処理をしているのかわかりませんでした。



記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82457  Re[41]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/10(Tue) 23:20:30)
    No82456 (ぎゅんぎゅ さん) に返信
    > 500MBを処理するのに
    >
    >
    > VBの旧CRC(integer) 4.0sec
    > VBの旧CRC(uinteger) 1.45sec
    > VBのMD5 1.2sec
    >
    > VBの新CRC 0.84sec
    > C#DLL 0.59sec
    >
    > でした。
    >
    > 劇的に速くなっています。
    >
    > ところでこれってどういうアルゴリズムを使っているのでしょうか?
    > データ読込と計算を並列化しているのでしょうか?
    > コードを見れば分かると思ったのですが
    > 見てもさっぱり何の処理をしているのかわかりませんでした。

    CRCの計算アルゴリズム(Crc32.NET)の方は、ループ展開による効率化ですね。

    全体の処理としては、前にも書いたようにデータ読み込みと計算処理の並列化です。
    読み込みと計算を順番にシーケンシャルに実行すると、読み込み実行、計算実行と順番に処理するため、読み込んでいる間は計算処理が動けません。

    読み込みを実行後、バックグラウンドスレッドで読み込んだバッファの計算を開始し、平行して次のバッファへの読み込みを実行します。
    こうすることで、計算処理がほぼ停止することなく全力で走り続けられるようになります。
    ※まあそれでもキャッシュに乗っていなければ読み込みはまず間に合わなくなりますが。
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82460  Re[42]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ -(2017/01/11(Wed) 10:11:50)
    なちゃ さん

    ありがとうございます。

    ところでずっと気になっているのですが
    MD5とこの高速CRCの計算の速度を比較した時、
    一度読み込ませた後
    (メモリにファイルが格納された状態)の二回目以降を比較すると上記で述べたように
    2倍程度の高速化が見込めます。

    しかし、通常CRCを求めるのに何度も同じファイルを計算しても意味がないので
    一度しか求めることはしません。

    そのため、一度500MBのファイルを2つコピーして、
    PCを再起動し、メモリをクリアした状態でそれぞれ別のファイルに対して
    MD5やCRCの計算を行って速度比較を行ったのですが
    結果、いずれも4sec程度となり、全く差異が見られませんでした。

    これって、結局、読込と計算を並列化したところで
    HDDからの読込がボトルネックになっているので
    ほとんど差異が表れないということでしょうか?

    となってくると、CRCはMD5よりも桁数が小さい分、
    異なるファイルでも同じ値になる確率が高く、安全性が低いので
    結局MD5を使う方が良いのではないでしょうか?

    これ以上は速度向上は見込めませんよね??






記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82461  Re[43]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ -(2017/01/11(Wed) 10:21:11)
    あと気になっているのですが、
    一回目の読込と二回目以降の読込で
    数倍程度、CRCやMD5の計算速度に違いが見られるのは間違いないです。

    それでてっきりメモリにキャッシュされているのだと思っていたのですが
    タスクマネージャーで4GB程度の大きなファイルを読み込ませる前と後のメモリ使用量を比較したのですが
    全く違いは見られませんでした。

    私の場合、OSの入ったCドライブをSSDを使い、データの入ったDドライブをHDDを使っているので
    SSDのドライブに仮想ドライブとしてキャッシュされたのかと思い
    ドライブの容量変化も比較しましたが
    全く差異は見られませんでした。

    それでは一体、どこにキャッシュされているのでしょうか?
    そもそもキャッシュされているから二回目以降速くなる
    というのは正しいのでしょうか?

     
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82463  Re[44]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/11(Wed) 12:15:44)
    メモリ使用量って何を見てますかね?
    Window7以降?とかならタスクマネージャのパフォーマンスタブで、キャッシュ済みだったかで見れたような気がします。

    メモリ使用量というのはかなり曖昧な表現なので、それだけでは何とも言えません。
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82462  Re[43]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/11(Wed) 12:12:26)
    今のハードディスクだと100MB/sかもう少し上くらいの転送速度の物が多い気がするので、まあそのくらいでしょう。
    SSDとかになると500MB/sを超えるような物もあったり、RAIDだと転送速度が上がったりするので、 一概に効果がある無いとは言えません。

    また、こういう数値を計算するのが、ファイルを保存した後などであれば、キャッシュにのっていることが多い可能性もあります。
    また、保存直後だとウィルススキャンがすでに裏で読み込んでいることもあります。

    まあそれはそれとして、CRCとMd5などの暗号ハッシュでは、その生い立ちや目的や機能が全く違うので、一概にどうとは言えません。
    CRCには誤り訂正機能もありますし。
    ただまあ、CRCはどちらかというと低負荷でハードウェア回路で簡単に実現できるとか、昔は大きなメリットがありましたが、今時にソフトで扱うする分にはそれほど有利な点は無いとは思います。


記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82464  Re[44]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ -(2017/01/11(Wed) 12:19:41)
    ちなみにOSはできるだけメモリを有効活用しようとしますので、余分なメモリを使わずにほっとくことはあまりありません。
    空きメモリがあればたいていそのうちキャッシュで埋まります。
    そこから新たに大きなファイルを読んでも、例えばキャッシュが書き換わるだけでトータルの物理メモリ使用量は変わらなかったりします。
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82467  Re[45]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ -(2017/01/11(Wed) 12:51:01)
    ありがとうございます。

    先ほど試したのは自宅のwin8 PCだったのですが
    キャッシュという項目がありませんでした

    いま、職場のwin7 PCで試したところ
    キャッシュという項目があり、そこの値がファイルを読み込むことで変化することが分かりました。
     
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82468  Re[46]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ -(2017/01/11(Wed) 12:54:50)
    なちゃさん

    あと、
    このプログラムを作ろうと思った動機は
    二つのHDDに同じファイルがあり、
    それらのファイルがバイナリレベルで等価かどうかを確かめたいためです。

    それぞれのHDDのファイルのハッシュを順番に求めて
    比較すれば、目的を達成することができるます。

    それで、いまHDDへのアクセス速度が律速しているわけなので
    二つのファイルが別のHDDに置かれているのであれば
    二つ同時にアクセスして、
    二つ同時にハッシュを計算すれば計算効率が上がるはずです。

    二つのファイルを並行してハッシュを計算するにはどのようにしたら良いでしょうか?



記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

■82471  Re[47]: VBでCRC32を高速で計算する方法
□投稿者/ 魔界の仮面弁士 -(2017/01/11(Wed) 13:04:58)
    No82468 (ぎゅんぎゅ さん) に返信
    > 二つのファイルを並行してハッシュを計算するにはどのようにしたら良いでしょうか?

    スレッドを 2 つ用意し、それぞれで計算させてみては如何でしょう。
    両方が終わったときの待ち合わせは必要ですが、それは Task.WaitAll などが使えるかと。



    CRC32 の各実装ごとの処理効率のみを比較したいのであれば、
    メモリを十分搭載した環境で、File.ReadAllBytes で一括読み込みした
    As Byte() に対する算出時間を測定すれば、ひとまず
    ディスクの読み取りキャッシュの差は除外できると思います。
    CPU 側のキャッシュメモリは別として。
記事No.82326 のレス /過去ログ140より / 関連記事表示
削除チェック/

<前の20件 | 次の20件>

<< 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 >>

ヒット件数が多いので過去ログ1〜140 までの検索結果 / 過去ログ141からさらに検索→

パスワード/

- Child Tree -