業務アプリでCRCを実装するらしい。
担当者が対象文字列を2進数に変換後、xor処理する過程を資料にしていたので、チラ見。
CRC処理
ほほぅ、CRCって名前は知ってるけど、こうやって処理するんだね。
対象文字列を文字コードに変換し、2進数にしてから、CRCパラメータの初期値でxorを取得。
後は、CRCパラメータの生成多項式で、xorを商部分が0になるまで繰り返し実行し、余り部分がCRC。
って書くと簡単だけど、実装は大変。
vbaでやってみた。
俺ロジック
まずは、上記ロジックをそのまま実装してみる。
そのまま処理を実装したので1ビット毎にxor取るから、めっちゃ処理が遅い。
10文字程度なら一瞬で終わるけど、業務アプリでは250文字を、何千~何万件を処理する事になる。
試しに1000件で、実行したら、数分かかった。
これを元に10万件を計算すると、5時間52分!
遅すぎだろww
配列ロジック
ネットで主流の最初に配列作って処理回数をすっ飛ばすロジックをC言語から、vbaに移植してみた。
やばいくらい早い。
1000件なんて、一瞬過ぎて計測できなかったので、実際に10万件処理させてみた。
結果、1.33秒!
早すぎだろっwww
xor法則
xorには、法則があって、その法則に当てはめた結果を事前に配列にしておくと、計算回数を激減させる事が出来る。
全部説明出来ないので、気になる方は、ネットで検索を。
ついでにxorを16ビット単位(今回のCRC実装は、CRC16-CCITT-FALSE)に実施しているので、xorだけで俺ロジックより16倍速い。
ビットシフトロジック
あまりに強烈だったので、配列使わないとどうなんだろう?と思って、配列無しの実装を試みるが、ここで、はまった。
全然、正しい結果が出てこない。
実は、配列より先に、こっち書き始めたんだが、どのネットの例を移植しても、正しい結果が出ないので、気分転換に配列ロジックを書いたんだよね。
CRCは左送りと右送りがあって、生成多項式(2進数)を左・右で逆転させなきゃいけないとか。
それで色んな例が氾濫してるみたい。
担当者が作った資料しか見てなかったので、CRCの仕様は知りませんw
しかも、vbaにはビットシフト機能が無いので、2倍や1/2の計算で結果を取得するんだけど、変数はLong型使ってるので、左ビットシフトを繰り返すとオーバーフローするという。
ネットの例を試すと結果が違う場合とオーバーフローする場合の2種類に分かれた。
仕方ないので、ビットシフト用関数作って、シフト後に上位16ビットを切り捨てる処理追加したら、オーバーフローしなくなった(Office 32bitなので、vbaのLong型は32bit)。
そしたら、それまでオーバーフローで結果取得出来なかった処理の1個で、初めて正しい結果が!
おぉぉぉっぅ、来たぁぁぁぁぁぁぁ。
処理速度は、配列ロジックに及ばないものの、10万件で34秒。
そうそう、処理内容は、ビットシフト。後は、生成多項式とのxor。
全アルゴリズム対応型ロジック
これで、俺ロジック、ビットシフトロジック、配列ロジックの3種類実装出来たので、最後の挑戦。
CRCって、パラメータによって種類がいっぱいあるので、全対応型を作る。
作るといっても、javaのソースがあったので、移植するだけだが。
移植すると、CRC16とCRC8の全アルゴリズムで、正しい結果が出た。
しかも、配列ロジックの配列を自動生成するので、処理速度も爆速。
これで、いろんなCRCに対応できるね~。
と、言っても、Long型が32bitなので、CRC32とCRC64は対応できず。
やっぱりネイティブバイナリ
まぁ、全部お遊びですよ。
実際の業務アプリは、担当者が独自ロジックで作って、10万件が90秒だったみたい。
やっぱりコンパイル出来る、ネイティブバイナリは処理早いな~。
これで配列ロジック実装したら、0.006秒で処理出来るんじゃない?