- PR -

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

投稿者投稿内容
川上
常連さん
会議室デビュー日: 2006/08/18
投稿数: 20
お住まい・勤務地: 東京
投稿日時: 2008-04-29 01:48
こんにちは、VB.NET2005で開発を行っております。

こんなやり方は普通は行わないと思いますが、
駆け出しの頃に試行錯誤で作成した処理で困っています。

画像を読み込み取得したバイト配列を文字列として編集(結合)してDBに登録し
DBに登録された文字列から2バイト区切りで取得しバイト配列に変換して
画像として画面に出力しています。

文字列からバイト配列に変換している処理
--------------------------------------------------------------------------------
ReDim sobj_Bytes(Len(pstr_BinaryString) / 2)
For sint_Index = 0 To Len(pstr_BinaryString) - 1 Step 2
  sstr_HEX = Trim(Mid(pstr_BinaryString, sint_Index + 1, 2))
  sobj_Bytes(sint_Index / 2) = CLng("&H" & sstr_HEX)
Next
pobj_Bytes = sobj_Bytes
--------------------------------------------------------------------------------

普通だったら、DB上もバイト配列型のImageタイプで作成して文字列にするなんて事は
行わないと思います(汗)  (その頃はImageタイプを知しませんでした。。。)

文字列上から2バイト単位でバイト配列にする処理(上記)で、
カナリのCPU負荷が掛かってまして複数の画像を表示する画面がとても重い状況です。

そこで、このような文字列をCPUの負荷を掛けることなくバイト配列に変換する
良い方法がございましたら教えて頂けますと非常に助かります。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2008-04-29 09:21
引用:

川上さんの書き込み (2008-04-29 01:48) より:
こんにちは、VB.NET2005で開発を行っております。

こんなやり方は普通は行わないと思いますが、
駆け出しの頃に試行錯誤で作成した処理で困っています。


そうでもないです。BLOB型やImage型はメンテナンスが手間なので、あえてHEXやBASE64に変換したり、あるいはファイル名のみをデータベースに格納し画像をファイルのまま保存しておくというのは多いです。

引用:

文字列上から2バイト単位でバイト配列にする処理(上記)で、
カナリのCPU負荷が掛かってまして複数の画像を表示する画面がとても重い状況です。


本当に負荷の原因は上記のコードですか?
各コードごとに処理にかかる時間などを計測して、そのFor文で時間がかかっている事を確認しているでしょうか?正直なところ、そんなに時間がかかるとは思えないものでして。「Len(pstr_BinaryString) 」をFor文に直接書かずに誘導変数を使うぐらいしか思いつきませんです。
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2008-04-29 11:32
ReDim を使うよりは、List(Of Byte) を使った方がいいでしょうね。
なんとなくですが、いろいろ無駄な処理が入っている感じがします。
そのせいで細かく遅くなっているのではないかと。

ただ、甕星さんの書かれているように「どこで遅くなっているのか」
は調べた方がいいと思います。

ちょっと C# で書いたのがこれ。

コード:

    string s = "82A082A282A4";
    List<byte> b = new List<byte>();
    for (int i = 0; i < s.Length; i += 2)
    {
        b.Add(byte.Parse(s.Substring(i, 2),
            System.Globalization.NumberStyles.AllowHexSpecifier));
    }
    byte[] bb = b.ToArray();


_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
川上
常連さん
会議室デビュー日: 2006/08/18
投稿数: 20
お住まい・勤務地: 東京
投稿日時: 2008-04-30 15:52
ご返信ありがとうございます。

各処理での処理時間を計ってみました。
----------------------------------------
1.リクエスト受信

2.データベースから抽出

3.文字列のバイト配列編集

4.レスポンス出力
----------------------------------------
リクエスト受信〜データ抽出は、0ミリ〜5ミリ秒程度でしたが
文字列をバイト配列に編集する処理では、データサイズによりますが
20ミリ〜70ミリ程度の処理レスポンスでした。
(※データサイズは 10000〜40000バイトです)

1画面に30枚ほどの画像を出力してるのですが、
パラパラと1枚づつ表示されてくような感じで現在は動いてます。

他機能でバイナリ配列型のImageを使用した画像出力ページでは
当変換機能を使用していない為か、サクサク画像が表示されます。

To「ぽぴ王子」さま
教えて頂きましたコードの、List(Of Byte) のVBの使い方が良く分りません。
VB版のサンプルを頂けると非常に助かります。。。

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

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

To「ぽぴ王子」さま
教えて頂きましたコードの、List(Of Byte) のVBの使い方が良く分りません。
VB版のサンプルを頂けると非常に助かります。。。


List(Of Byte) は VB の書き方で、コード上の List<byte> が C# の
書き方だったので、ちょっと混乱させてしまったかもしれませんね。

List(Of Byte) 厳密には Byte は型名ですが、MSDN を見ると List(Of T)
と表現されています。
ジェネリッククラスと言って、T で指定された型のみを扱うリストという
意味でこう書きます。
List(T) ジェネリック クラス (System.Collections.Generic) (msdn.microsft.com)

元のコードでは、List<byte> b という変数を定義して、そのリストに
b.Add で変換した値を追加しています。そして最後に b.ToArray() で
一度配列に変換しています(リストのまま使うのであればそこは必要
ないかもしれません)。

それを VB に変換したものがこちらです。

コード:

    Dim s As String = "82A082A282A4"
    Dim b As New List(Of Byte)
    For i As Integer = 0 To s.Length - 1 Step 2
        b.Add(Byte.Parse(s.Substring(i, 2), _
                         System.Globalization.NumberStyles.AllowHexSpecifier))
    Next
    Dim bb As Byte() = b.ToArray()


個人的にはテーブルに手を入れてしまって、現在テキストで登録されて
いる画像データをバイナリで保存し直すのが素直かなぁとも思いましたが
そうもいかない理由もあるかもしれないですしね。
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
川上
常連さん
会議室デビュー日: 2006/08/18
投稿数: 20
お住まい・勤務地: 東京
投稿日時: 2008-04-30 16:36
「ぽぴ王子」さま
ご返信ありがとうございました。

頂きましたサンプルソースの通りに記載してみましたところ、
20ミリ〜70ミリ秒かかってたのが、1ミリ〜2ミリ秒で処理が完了します。
(やっとサクサク画像が表示されるようになりました) 超Goodでーす!!

もう少し調べてみたら、バイト配列に型変換をしつつ代入している
次の文でレスポンスが悪化していました。
------------------------------------------------------------
 sobj_Bytes(sint_Index / 2) = CLng("&H" & sstr_HEX)
------------------------------------------------------------
この代入文って変でしょうか?

「ぽぴ王子」さまのご回答で解決したのですが、少し気になって・・・
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-04-30 16:54
Convertクラスのメソッドを使ったほうが楽だと思いますよん。
# 処理速度については計ってないのでわかりませんが

コード:
 sobj_Bytes(sint_Index / 2) = Convert.ToByte(sstr_HEX, 16)


rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-04-30 17:19
引用:

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

------------------------------------------------------------
 sobj_Bytes(sint_Index / 2) = CLng("&H" & sstr_HEX)
------------------------------------------------------------
この代入文って変でしょうか?




左辺がByte型で右辺がLong型なのがちょっと気になりました。
ただ、CLngをCByteに直しても実行時間は特に変わらないみたいですね。

それ以外では特に変だとは思いませんでしたが、
括弧内で文字列連結をしているのが遅い原因なのではないかなと思います。

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