- PR -

バイナリ文字列をバイト配列に変換

投稿者投稿内容
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2008-04-30 17:33
rain さんの書かれているとおり、Convert クラスを使った方が
楽だったですね。

乗りかかった船なので、ちょっと僕も見てみます。
説明しやすいように行番号をつけてみました。

コード:

1: ReDim sobj_Bytes(Len(pstr_BinaryString) / 2)
2: For sint_Index = 0 To Len(pstr_BinaryString) - 1 Step 2
3:     sstr_HEX = Trim(Mid(pstr_BinaryString, sint_Index + 1, 2))
4:     sobj_Bytes(sint_Index / 2) = CLng("&H" & sstr_HEX)
5: Next
6: pobj_Bytes = sobj_Bytes


まず1行目。
sobj_Bytes の型がわかりませんが、Byte 型でしょうか。そこは
ちゃんとあわせておいた方がいいと思います。
あとは先に書きましたが配列を使って ReDim を行うと結構パワーを
使いそうな気がするので(なんとなくですが)リストを使った方が
いいでしょうね。インデックスも意識しなくてよくなるし。

3行目。
Mid は意外と遅いかもしれません(計ってないですが)。
Microsoft.VisualBasic 名前空間にある便利な関数は、個人的には
VB6 あたりからの移植を意識して作られているものというイメージが
あるので、自分で VB で組むときもあまり使いません。
あと Trim の必要はないですよね。このあたりのコストがちょっとずつ
積み重ねられて遅くなっているのかな?と推測しました。
あと一度変数に入れるのもちょっとしたコストがかかりそう。

4行目。
配列を使っているので、いちいち sint_Index / 2 という式が入り
これはこれで結構読む側も面倒くさいのと、小さなコストアップに
つながっている気がします。
CLng を使っていますが、一度 Long に変換して、それを sobj_Bytes
(Byte かな?)に変換するのはかなり効率が悪そうです。
それなら最初から CByte を使うか、Convert クラスで変換して
しまった方がいいと思いました。

6行目。
sobj_Bytes を pobj_Bytes(これまた型がわかりませんが、Byte じゃ
ないのかしら)に代入していますが、同じ配列なのだとしたら最初から
pobj_Bytes を使った方が良さそうですね。

とまあ、こんな感じでこまかーい無駄がちょっとずつ重なって遅く
なっている感じがしました。
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-04-30 18:30
それでは私もノリかかったヤキソバということで…

引用:

ぽぴ王子さんの書き込み (2008-04-30 17:33) より:

あとは先に書きましたが配列を使って ReDim を行うと結構パワーを
使いそうな気がするので(なんとなくですが)リストを使った方が
いいでしょうね。インデックスも意識しなくてよくなるし。


インデックスを意識しなくてすむというのは賛成ですが、
今回に関して言えば要素数は最初にわかっていますので、
Byte配列の宣言で全く問題ないと思います。
# ただ、ReDimで同じ変数名を使い回すよりは、この処理でしか使わない変数を
# Dimで宣言したいです。

逆に何も考えずにList(Of Byte)を使うと、Add()で要素が追加されることで
メモリの再割り当てが必要になるため、かえって遅くなる可能性があります。
もっともこれは、List(Of Byte) の初期化のときに要素数を指定すればいいだけですが。


ちなみに、ジェネリックを使うことで実行効率がどう変わるかも、密かに
気になってますが、私自身がたぶん理解できないので言及は避けます(ぉ
川上
常連さん
会議室デビュー日: 2006/08/18
投稿数: 20
お住まい・勤務地: 東京
投稿日時: 2008-04-30 21:08
「rain」さま、「ぽぴ王子」さま
色々とご教授いただきありがとうございます。

Convert.ToByte(sstr_HEX, 16) の方法を試してみましたところ、スゴイです!!
List(Of Byte)の方法と変わらずメチャx2早いです。

Convert.ToByte(sstr_HEX, 16)と、List(Of Byte)の方法で時間を計ったので
以下に掲載します。
※計測では14枚の画像を出力するのに必要とした時間を計りました。
--------------------------------------------------
1)List(Of Byte)  →  100ミリ秒
2)Convert.ToByte →  67ミリ秒
--------------------------------------------------
Convert.ToByteの方法の方が若干早かったのですが、
指摘があった初頭に配列要素数を決めたList(Of Byte)の方法は試してません。
初頭から配列要素を決めて.addをしない方法だと同等の時間になるような気もします。

今回は、Convert.ToByteの方法を使用させて頂きます。 (^^

文字から16進数のバイナリに変換するのに、Convert.ToByteなんて方法もあったのですね。
色々と勉強になり、ありがとうございました。
(明日のクライアントの驚く顔が楽しみだー♪)

ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2008-05-01 06:34
引用:

rainさんの書き込み (2008-04-30 18:30) より:

インデックスを意識しなくてすむというのは賛成ですが、
今回に関して言えば要素数は最初にわかっていますので、
Byte配列の宣言で全く問題ないと思います。
# ただ、ReDimで同じ変数名を使い回すよりは、この処理でしか使わない変数を
# Dimで宣言したいです。

逆に何も考えずにList(Of Byte)を使うと、Add()で要素が追加されることで
メモリの再割り当てが必要になるため、かえって遅くなる可能性があります。
もっともこれは、List(Of Byte) の初期化のときに要素数を指定すればいいだけですが。


これは確かにその通りですね。取得した文字列の長さ÷2で要素数が
求められるわけですから、配列でもかまわなかったです。
List(Of Byte) でのメモリの再割り当てを考えると、最初に要素数分
確保しておく方向でいいのかなと。
# ReDim より Dim も賛成(笑)

引用:

川上さんの書き込み (2008-04-30 21:08) より:

Convert.ToByte(sstr_HEX, 16) の方法を試してみましたところ、スゴイです!!
List(Of Byte)の方法と変わらずメチャx2早いです。


うーんと、Convert.ToByte を使う方法と、List(Of Byte) を使う方法は
同じ土俵の上にあるわけではないので、比較対象にはならないかと。
Convert.ToByte と比較するなら Byte.Parse の方法ですね。
List(Of Byte) であれば ReDim と比較すべきです。

いやまぁ速くなったのであればそれでかまわないですが。

引用:

文字から16進数のバイナリに変換するのに、Convert.ToByteなんて方法もあったのですね。
色々と勉強になり、ありがとうございました。


処理系によっていろいろと最適な方法は違ってくると思います。
危険なのは考え方が固定されてしまうことで、以前はこうだったからこれで
イケるはずで止まってしまうと進化できないので、いろいろと試行錯誤して
みるのがいいと思います。
あとは MSDN をディスプレイに穴が開くほど眺めてみて、どんなクラスが
あってどんなメソッドやプロパティがあるか、ある程度は頭に入れておくと
いいんじゃないでしょうか。
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。

スキルアップ/キャリアアップ(JOB@IT)