野鳥紀トップページへ 野鳥の写真集・総合目次へ 観察野鳥一覧表へ 制作メモのページへ ご案内のページへ 一シギ二タカ三ツグミへ移動 動画集「ビデオカメラと野鳥」のサイトへ移動

VisualStudioメモ

VisualStudioCommunity2019

200506
フリーのVSをインストールしました。
動機は、いつも使っているHSPで、テキストファイルの操作に11分かかる
スクリプトを作った事です。
これではどうしようもないと思い、C言語か何か、コンパイラを探しました。
結局、VSに挑戦してみる事にしました。
色々かじってみたのですが、Cでは画面が作れない、C++は難しい、
という事で、現在、C#で右往左往しています。
以下は、極めて個人的なもので、系統だった知識もない素人が作る備忘録で、
単なるドタバタの記録です。
なお、先の11分の件、今は解決しています。
CやC#を調べていくうちに、HSPでの私のスクリプトの欠陥に気付きました。
改良した結果、HSPでも500ミリ秒で終わります。

200708
true、false、if (!a)
未だにif文の書き方がおぼろげです。

まあ、間違っても、その場で赤い波線になるので、何とか処理出来ていますが。
よくやるのがこれ、if (a = fales)、です。
2か所も間違っています。
==とfalseのスペルです。

これに気が付かないので、どうしても赤い波線が消えません。
やむを得ず、例文などからそのまま、if (a)とかif (!a)とか書き直して凌いでいます。
もちろん、!を付けるのが正しいのか、付けないのか分かりませんので、試行錯誤します。
それぞれ実行して、どちらか予定通りの行動になる方を採用する、という段取りです。

これを回避する為に、a=bの形式にしたいのですが、一方がtrueかfalseの場合、先のスペルミスがあります。
何しろ、いくつもの選択肢があります。
まず、引用符""が必要なのか、大文字なのか小文字なのか頭文字だけ大文字なのか、等、無限に試行錯誤が続きます。

長年=一つで済ませてきましたので、==に気付かないのはやむを得なかったと思います。
false、trueは、最近、こう書けばいいと気づきました。
if (a == false)、です。
ネットでは、ほぼ全部、if (!a)、と書いてあります。
if (a == false)、と書いてもらうと分かり易いのに、なぜ省略するのでしょうかね。

今日、気付いた事が2点、
falseは、フェイルスではなく、フォールスと発音する事、
VSのエディタでは、正しくfalseとタイプすると、文字が青色に変わる、という事です。
これで、今後は大丈夫でしょう。多分。


200707
C#、テキストボックスへの表示にかかる時間

200705付けでメモした事で、全く同じ作業なのですが、2度目の方が作業時間がかかってしまう、という現象がありました。
かなり大きなテキストファイルの更新作業です。670KB程度、行数は30000行ほどのファイルです。
このファイルの適当な位置に、新しく10数行の文字列を挿入します。挿入位置は末尾や先頭ではありません。途中です。

フォームで画面を作ります。テキストボックスを数個、ボタンを数個です。
テキストボックスのmaxlengthは0にしています。
こうすると、表示サイズの制限がなくなるとの事です。

起動時に、目的のファイルを読み込んで、表示までしておきます。
ボタンにコードを埋め込んで、実際の作業、文字列の挿入です。
具体的には、以下の作業になります。
まず、念の為、ファイルはもう一回読み込み、表示します。
読み込んだテキストに、文字列を挿入して、再度表示、保存です。
念のため、上書きしないように、保存する時のファイル名は変えています。
ですので、何度でもボタンを押して、同じ作業が出来ます。

いつも作業時間を計っています。
HSPでは3秒かかる作業で、C#で代替えして、もう少し早く出来ないかという事が動機でした。
結果、320ミリ秒程度で終わります。

ただ、ここで問題があって、ボタンをもう一回押して、同じ事を再実行させると600ミリ秒かかってしまいます。
これは何だ、となって、時間の計測を細かく分割しました。
ファイル読込に何ミリ秒、表示に何ミリ秒、という感じです。

これで、簡単に原因が分かりました。
一回目の実行では、読み込みに要する時間は10ミリ秒程度でした。これが2回目以降は270ミリ秒程かかっています。

この結果は、こう考えるよりありません。
C#では、テキストボックスに再表示する際は、表示してある内容と同じテキストだったら、表示を省略する。
どうしているのでしょうかね。チェックサムみたいな物があるのでしょうか。
コードを読み切っているのでしょうか。このコードなら再表示の必要なし、という判断をしているとは思えませんが。
だとすると、向こうが偉いという事になります。
まさか、文字数とかファイル名だけで判定しているはずもないでしょうし。

更に、もう一つ、大事なことに気付きました。
C#で、ファイルが大きい時など、テキストボックスへの表示をさせなければ、圧倒的に速くなる。
今回のケースでは、表示を省略すると、50ミリ秒で終わることになります。
比較の為に挙げた、HSPでの3秒という時間には、表示時間が含まれていませんでした。
つまり、C#が圧倒的に速い、ということです。

さらに、ずーっと下のメモで、色々な比較をしています。
この時、表示に時間がかかるという事は考慮していたのか気になります。
やはり、正確な比較をするなら、C#は、C言語といい勝負をするのかもしれません。



200705
C#、文字列の分割と結合
テキストファイルの途中に文字列を挿入する作業に苦労しています。
文字列の末尾ではなく、途中に小さな文字列を追加しようとしているのですが、なかなかうまく行きません。
HSPだと、noteadd 追加するブロック,追加する行番号,0、という一行で済む作業ですけど。

C#で、文字列の途中に文字列を挿入する手段を探しましたが、簡単な方法が分かりません。
簡単ではないというような記事もあります。

分かったのは、
元の文字列を、行単位に分割する。
追加する位置を境にして、前後のブロックに分けた文字列を作る。
前のブロックの末尾に今回挿入するブロックを追加する。
その後ろに、先に分けておいた後半部分のブロックを追加する。
という手段です。これ以外にはなさそうです。

上の方法で試しますが、すんなりとは行きません。
分割する時、前半のブロックの末尾が改行だけの行になっていて、これを連結すると、その改行だけの行が消えてしまいます。
一行短く仕上がってしまいます。
やむを得ないので、連結する時、改行を一行追加して辻褄を合わせました。

この作業、現在、HSPでは3秒強かかります。
サイトマップファイルに新しいページを登録する作業です。
ファイルは30000行660KBあります。
一応、同じ種類のページはまとめておきたいものですから、末尾に追加とはいきません。
今のところ、出来上がったテキストを保存する作業を入れていませんが、C#だと、300ミリ秒ほどで終わります。
C#に変える効果がありそうです。

どうやら正解が分かりました。
途中で配列にしたものを文字列に戻して、その文字列同士を連結したのがまずい様です。

完成後の行数、文字列を挿入した作業後の行数は分かります。
最初に、その長さの配列を宣言しておきます。
元の文字列も挿入する文字列も配列に変換します。
完成後の長さ分確保していた配列に、前半部分の配列、挿入する部分の配列、後半部分の配列を、位置を指定してコピーします。
最後に配列を文字列に変換します。
これで、改行だけの行も残ります。

完成したとして、ファイルの読み込み、連結、ファイルの書き込み、までの時間は330ミリ秒ほどです。
HSPでは3秒かかっていました。

ただ、連続して実行すると、2度目には600ミリ秒かかります。原因不明です。
原因が分かりました。テキストボックスへの表示時間です。これについては、改めて、項を変えてメモします。




200702
tt.Replace("\\", "/");

とあるフォルダのファイルリストを取ると、次のような文字列が出てきます。
G:/main-data/code/VS2019/CSDATA/temp20\200625mg.htm
\を/に変えたいのですが、うまく行きません。
tt.Replace("\\", "/");
が言う事を聞きません。

200701
C#、降順のソート
listBoxを使ってみる事にしました。
フォルダにあるファイルの一覧を作って、リストボックスに表示させます。

まず、ListBoxではなく、listBoxですね。まずここでエラーと言いますか、例の赤い波線です。
どうやら規定では、昇順にソートされる様です。
私の希望では降順でソートして表示させたいのです。
基本的に、ファイル名に日付を付けていますので、一番新しいファイルを一番上に置きたいのです。

全くの付け焼刃です。例によって、ネットを探しました。
これが面倒でした。様々なソートの方法が有るようですが、どれも分かりません。
構文が長くて、意味不明です。2行に渡る物もあります。
C#のバージョンによっても違うのかも知れません。
やはり系統立てて勉強していない事へのしわ寄せでしょうね。
目的は、単純に文字列の配列を昇順に並び換えたいだけです。
HSPだと、簡単に、sortnote files,1、とするだけなのですが。

ようやく、見つけました。
Array.Reverse(files);、で目的達成でした。



200623
VSエディタの起動時間

VSのエディタの起動にかかる時間が気になってきました。
C#で、デスクトップにsinファイルのアイコンを作って、そのアイコンをダブルクリックしてVSのエディタを起動しています。
これが、開き終わるまでの時間です。

編集しているテキストは、Form1.csだけです。これが30KBで、あと、Program.csというファイルがあります。1KBです。
csファイルはこれだけです。
そこで、時計を横目で見ての計測ですので、正確さはありませんが、ダイアログで、準備が完了しました、と出るまでに8秒ほど、
そのダイアログで、バックグラウンドで云々とあって、ダイアログが消えるまでに更に8秒ほどかかります。

エディタに慣れてくると、この辺りも気になってきます。


200620
C#、byte[]

昨日発見したbyte型ですが、ある程度の文字列を扱うので、大きめに確保しておきました。
byte[] aa = new byte[1000000];
そして、文字のアスキーコードを順番に入れていき、終わった所で終端の0を入れます。
その後で、Shift_JISの文字列に変換します。
string tt = System.Text.Encoding.GetEncoding(932).GetString(aa);

当方の目論見通りです。ちゃんと表示され、保存も出来ます。
ですが、よくよく調べてみると、ファイルの大きさが、最初に確保した1000000バイトのままです。
それこそVSCodeで強引にhexダンプしてみると、文章が終わった所から以降には全部、0が並んでいます。
Shift_JISでは考えられない世界です。これがUnicodeなのでしょうか。私の無知なのでしょうか。

やむを得ず、完成後のバイト数をしっかり計算して、必要十分な領域を確保して、回避しました。
それにしても、byte型に関しては、もう少し勉強が必要かもしれません。
一番の原因は付け焼刃でやっている事なのですけど。


200619
C#、char、byte、Shift_JIS
C#のcharは16ビットです。8ビットはbyteという型があります。
これは許せません。これに気付くまでに3日かかりました。

普通は一文字ずつメモリというか配列に収めるならcharでしょう。
そのつもりでやっていったら、どうしても型変換のところで止まります。
char m[0] = 65;
char m[1] = 66;
char m[2] = 0;

これをstrngに変換しようとしても出来ません。
強引に変換しても、結果は文字化けしています。
VSのエディタの警告やブレークポイントでのデータを見ると、UTF-8になるよ、みたいな表示です。
理解はできません。

正解は、
byte m[0] = 65;
byte m[1] = 66;
byte m[2] = 0;
です。
これで期待通りのShift_JISの文字列”AB”を作れます。
(何故か、末尾の0?='\0'は必要なし。)

このところ、文字列の連結で試行錯誤です。
言語も、C、C#、HSPを右往左往しています。
C#の速度がどうにも遅いので、調べたら、StringBuilderクラス、というものがありました。
これを使うと、Cに近い速度が出ます。
よく見たら、Cではcharの配列を使っていました。
文字列を連結するのではなく、インデックスを指定して直接書き込んでいます。
そこで、HSPに戻って、pokeを使って書き込みするようにしたら、こちらもC#並みとはいきませんが、かなりな速度になりました。
そこで、戻ってC#です。
C#でも配列に書き込んだら、訳の分からないStringBuilderクラスなど使わなくてもいいのではないかと考えました。
そこで、当然、私の知識ではchar[]を使えばいい、はずです。
この間、3日悩みました。
正しくは、byte[]でした。

文例などに、byte型とかあるので、何だろうかとは思っていました。




200619
C#、型

C#の変数の型について、大して違わないだろうと、これまで何も調べずに使っていました。
と言いますか、どこに書いてあるか分かりませんでした。
最近、型変換がうまく行かないので、探していて、ようやく、分かり易いページを見つけました。

思っていたものと違いますね。
charは16ビットです。Unicodeのせいでしょうかね。
byteという型があって、これが8ビットです。1バイトですね。
intは32ビット、とあります。

Cでは、
charが8ビット
intが通常32ビット、
shortが16ビットとあります。ただ、Cはコンパイラ次第のようです。

念のため、VSのCではどうなのか、調べたのですが、見つけられません。
いえ、検索すると、intが4バイトというページがあります。32ビットですね。
ただ、残念なことに、これがどの言語の規定なのかが分かりません。
考えると、OSの32ビットと64ビット違いによる関連はないのでしょうかね。少し心配です。

HSPでは、
変数の宣言がありませんので調べるのに苦労します。
intは型変換です。小数点を切り捨てるのに使います。多分。
基本が整数なので、普通に割り算すると整数が帰ります。多分。
10進数の範囲は32ビットと書いてあります。これが制限なのでしょう。


200617
VS、上書き保存
Cの編集中、VSのエディタで上書き保存のアイコンをクリックするとダイアログが開いて、出力-デバッグ.txtというファイルを保存しようとする。
どうやら、コンソール出力の内容を保存するみたい、リダイレクトだったか、既定かな。便利と言えば便利。
コンソールを閉じていても出てくる時がある。
何か知らない構造があるのだろう。
200617
C、open
ファイル読込の際、rでもrbでも同じ結果になる。読込方次第か。
fp = fopen(fpath, "r");
200617
C#、byte[] bytes
byte[] bytes = SiftJISenc.GetBytes()について調べてみました。

76C2CC・・というテキストを読み込ませ、
変数に代入し、直下にブレークポイントを置くと、実際の数値をみられます。

データは以下の通りです。
bytes[0]=55= "7"
bytes[1]=54= "6"
bytes[2]=67= "C"
bytes[3]=50= "2"

つまり、アスキーコードが入るという事です。

ついでに、文字に戻すには、
char mo = (char)bytes[0];
char mo2 = (char)bytes[2];
UTF-16で戻ってしまう。困った。(これは間違い、勉強不足の頃の話)

200617
C#、ブレークポイント

Cではどこにでもブレークポイントが置けます。
C#ではコードのある行でないと置けません。
これが分からずに、再起動を繰り返しました。

200616
スクリプト、コード

エディタで作るプログラムのソースファイルの中身をなんというか、迷っていました。
今後は、HSPはスクリプト、その他の言語はコードと表現する事で統一します。
HSPのエディタは、HSPスクリプトエディタとなっています。
VSの方はMicrosoftVisualStudioCommunity2019となっていて、ここでは判断できませんが、ヘルプの中にはコードと書いてあります。

200615
C、strcat
strcat(aa,bb);
この前に、aa[0]='0';が無いとエラーになる。

200615
VSCode、HEX表示

VCCodeに16進表示の拡張機能をインストールしました。
下のプログラムの確認の為に使います。
この操作方法に毎回迷います。どうしたら16進表示になるのかです。

あちこちメニューをめぐって何とかなるのですが、今回間違いのない方法を見つけました。多分。
ファイルを読み込んで、ファイル名が表示されている所を右クリック、
そのプルダウンメニューの最下部にShow Hexdumpと出ています。

Shift_JISファイルが、いつも、文字化けしています。UTF-8で読み込まれています。
下のエンコーディングの所から、読み直すことが出来ますが面倒です。
ウーザー設定に初期設定がありました。

200611
C#、StringBuilderクラス、言語別実行速度比較、poke
C#で満足できるだけの速度を出せました。
ネットは、早い、という記事を見ます。ここまで信じられない話でした。
恥ずかしながら、ここまでのバタバタをまとめておきます。

作業は、テキストファイルの16進表示です。100KBのテキストファイルを変換してみました。
(実際には、その他、多少の副次的な作業もするのですが、中心の作業は16進変換です。)

という事で、forにしろrepeatにしろ、100000回のループが必要です。
最初にHSPで作ったものは、100KBのファイルを処理するのに11分かかりました。
いつものやり方で、冗長なスクリプトで作るとこうなります。
これは、スクリプトを見直して、39秒までには縮めました、(下の一覧表の*列の記号で、A、以下同じ)
しかし、この速度では役には立ちません。

そこで、コンパイラで、となります。
VisualStudioCommunity2019をインストールしました。
ついでに、VSCodeも落としました。
(後で気づいたのですが、このVSや、VSCodeには、16進表示の機能が付いていました。)

色々の言語を試しましたが、総合的な問題でC#に行き着きます。
当初、C#では期待通りの速度は出ませんでした。HSPより多少いいか、という程度でした。
そこで、調べていたら、文字列の連結には、StringBuilderクラスというものがあって、これが早いそうです。
以下、このStringBuilderクラスに到着するまでの経過です。

最初に、VBで試しました。
しかしながら、付け焼き刃の知識では何ともなりません。
VSの文字コードは、基本Unicodeだそうです。
ここまで扱ってきた文字コードはShift_JISだけでした。
Shift_JISのファイルを読み込んで、Unicodeで処理されるので、多分、変換してShift_JISのコードを出力する、となると思いますが、この変換がうまく行きません。
(この時点では、こんな風に考えていましたが、C#で何とか出来た現在、C#もVBもほとんど変わらないみたいですので、今なら何とかなるのかも知れません。Shift_JISで読み込んで、そのまま処理して、出力もShift_JISを指定して出力する。でしょう。)

対象のテキストファイルを、最初からメモ帳などでUnicodeに変換して処理するといいじゃないか、となります。
長年の事で、これが許せません。BOMとか4バイト一文字とかに抵抗があるのです。
やはり、文字は1バイトで処理できないといけません。(根拠なし。面倒だというだけです。)

そこで、先のVSでCに挑戦しました。
C言語については、昔、ほんの少しですが経験がありましたので。
便利な世の中です。ネットを探すと、例文が沢山出てきます。
それを継ぎはぎすると何とかなるものです。以下同じ。
それに、VBで悩んだUnicodeが出てきません。Shift_JISをShift_JISのまま読込め、そのまま処理出来ました。
VCでは、コードのファイルもShift_JISで保存されています。

Cで試すと、100KBの作業でも78ミリ秒で終わります(B)。
ただ、残念な事に、コンソールモードです。
Cではデスクトップの画面が作れません。どんなに探しても、フォームエディタを見つけられませんでした。

これには、便法ですが略式の解決方法があります。
画面処理はHSPで済ませて、実際の作業は、execでCの実行ファイルを起動します。H
この方法でやると、100KBの処理を700ミリ秒で終わります。(C)
待たされたと感じない時間です。
これで、実用上は問題ないのですが、ちょっと見苦しい気がします。

そこで、C++です。
確かに、ネットの情報を駆使してVSのメニューを掘り下げると、フォームエディタは出てきます。
ただ、ビルドしてもコンソール画面しか出てきません。
コードの書き方も全く分かりません。文法がCとはかけ離れています。
ネットにはCと大して変わらないとありますが、とてもそのようには思えません。

やむを得ず、C#を試しました。
C#だとフォームエディタは簡単に出現し、編集もできました。ボタンやテキストボックスなど簡単に取り付けられます。
マウスのドラッグでボタンなどの配置場所を指定できます。
HSPだと配置場所はスクリプトに座標の数字を書き込んで行きますので、C#の方が簡単です。
コードの配置場所もすぐ見つかりました。
private void button1_Click(object sender, EventArgs e)
の下に書けばいいのです。
ここに、ネットからの例文をコピーして多少変数をいじるだけで動きます。

で、試した結果、100KBの処理に16秒かかりました。ミリ秒ではありません。(D)(E)
こんなものかと思いました。コンパイラではありません。C#は中間言語なのです。
HSPよりはいいけど、秒の単位が必要なら、使うのに躊躇します。
そこで、順番としてはC++に向かったのですが、上のメモの通りです。
この間、他の言語も調べました。
GoとかFreeBASICとかです。
いずれも、デスクトップ画面を作れるかがよく分かりませんでした。

やむを得ず、C#に戻りました。
ここでようやく、StringBuilderクラスを知りました。
これを使うと、驚きです、同じ処理が151ミリ秒で終わります。(F)(G)
C並みとは言えないにしろ、これに近い、抵抗のない数字です。
それに、C#だけで画面から処理まで完結できます。

これで、ネットでの評価に近い数字になりました。
C++の迷路をさまよう必要はなく、HSPからCの実行ファイルを呼び出す必要もありません。
手探り状態ですけど、C#で何とかなりそうです。

一段落した所で、各言語のコードやスクリプトを比較していたら、幾つか気付いたことがあります。

HSPでは、文字列の足し算(連結)をしていました。
ここまでの経過で、文字列の連結には時間がかかる事を知りました。
HSPにも文字列を直接操作する手段があります。pokeです。
元々、変換元からの取り出しにはpeekを使っていました。
それでも、pokeを使わなかったのは、peekはメモリからの読み出しで、pokeはメモリへの書き込みです。
これに、多少の躊躇がありました。
それに、多少は早くなったとしても、そんなには違わないだろうと思っていました。
しかし、C#での事で、試してみる価値がありそうな気がしてきました。

HSPのスクリプトをpokeで作り直してみました。
爆速です。
39秒かけていた100KBのテキストの変換が0.516秒で終わりました。ミリ秒の単位で終わります。(H)
こうなると、HSPでの作業に抵抗はありません。
C、C#での騒ぎが何だったのかという事にもなります。

Cでは最初からポインタと配列で作業しています。つまり、メモリへ直接書き込んでいました。(B)
偶然、参考にした文例がよかったのでしょう。
あ、恥ずかしながら、配列とポインタが同じものだ、ぐらいは知っていました。

Cにも文字列の連結があります。一応。これも試しました。
連結だと、Cでも遅くなります。100KBの変換で2.8秒かかりました。(I)(J)


処理にかかる時間に関して一覧表を作りました。
言語 20KBのテキストでの作業   100KBのテキストでの作業
処理時間(秒) Cを1とした倍率   処理時間(秒) Cを1とした倍率
A HSP 1.703 106.4   39.860 511.0
B C(コンソール) 0.016 1.0   0.078 1.0
C HSP+C 0.653 40.8   0.703 9.0
D C#(debug) 0.393 24.6   15.683 201.1
E C#(releace) 0.319 19.9   8.092 103.7
F C#(sb:debug) 0.133 8.3   0.155 2.0
G C#(sb:releace) 0.135 8.4   0.151 1.9
H HSP(poke) 0.329 20.6   0.516 6.6
I C(strcat) 0.265 16.6   5.563 71.3
J C(sprintf) 0.140 8.8   2.813 36.1


以下は作業中のメモです。
System.Diagnostics.Stopwatch()を使って、時間を表示させました。
(HSPでは、GetTickCount、C#では、GetTickCount())

C#の作業時間、(F)
20KBで、(0, 2, 0, 123, 8, 合計133ミリ秒)
100KBで、(1, 12, 0, 132, 10, 合計155ミリ秒)
という結果です。いずれもデバッグモードです、驚きました。

releaceモードだと、(G)
20KBで、(0, 2, 0, 133、合計135ミリ秒)
100KBで、(1, 10, 0, 140、合計151ミリ秒)

合計以外のコンマ付きの数字は、各セクション毎の所要時間です。
テキストファイル読込、16進数変換、16進数整形、mesboxへの表示、16進数ファイルの保存、の順番で表示しています。
コンマ付き数字が4個の結果は、mesboxへの表示と16進数ファイルの保存の合計です。

こうしてみると、時間のかかっているのは、変換結果のボックス表示の時間です。
他の作業には時間がかかっていません。
コードの間違いか、何やら、タイムラグみたいなものがあるのかも知れません。
あるいは、並行処理みたいなもので、実際の処理は他所でやっているとか。
あるいは、グラボの性能が悪いだけ、かも知れません。


簡単にそれぞれのスクリプトとコードを書き出しました。
肝心の所だけです。本来は、多少の修飾があります。

HSP、単に文字列の結合、(A)
repeat len
  one=peek(sjistext,cnt)
  hextext=hextext+strf("%02x",one)
loop
実行結果は、20KBで、1.703秒、100KBで、39.860秒


C、コンソールモード、配列に直接書き込み、(B)
for (i = 0; i < size; i++) {
  one = buf0[i]
  mae = one / 16;
  sprintf(mozi, "%X", mae);
  buf[ctr] = *mozi;
  ctr = ctr + 1;
  usiro = one % 16;
  sprintf(mozi, "%X", usiro);
  buf[ctr] = *mozi;
  ctr = ctr + 1;
}
buf[ctr] = '\0';
結果、20KBで、16ミリ秒、100KBで、78ミリ秒、(デバッグモードのデバッグなし開始)


C#、単に文字列の追加、(D)、(E)
for (int ctr=0;ctr<len;ctr++)
{
  hextext += bytes[ctr].ToString("X2");
}


C# StringBuilderクラスを使って文字列を追加、(F)(G)
System.Text.StringBuilder hextext = new System.Text.StringBuilder();
for (int ctr = 0; ctr < len; ctr++)
{
  hextext.Append(bytes[ctr].ToString("X2"));
}
string hextext0 = hextext.ToString();
結果は、20KBで、135ミリ秒、100KBで、151ミリ秒



HSP、pokeで書き込み、(H)
repeat len
  one=peek(jistext,cnt)
  mae=one/16
  asc=strf("%X",mae)
  poke hextext,ctr,asc
  ctr=ctr+1
  usiro=one\16
  asc=strf("%X",usiro)
  poke hextext,ctr,asc
  ctr=ctr+1
loop
poke hextext,ctr,0
実行結果は、20KBで、329ミリ秒、100KBで、516ミリ秒


C、コンソールモード、連結方式でも試してみました。(I)
strcatで連結していきます。
for (i = 0; i < size; i++) {
  mae = buf0[i] / 16;
  sprintf(mozi, "%X", mae);
  strcat(buf, mozi);
  ctr++;
  usiro = hitomozi % 16;
  sprintf(mozi, "%X", usiro);
  strcat(buf, mozi);
  ctr++;
}
buf[ctr] = '\0';
結果(H)、20KBが、265ミリ秒、100KBで 5563ミリ秒。(デバッグモードのデバッグなし開始)


C、更に、sprintfを連結して二文字ずつ作業すると、(J)
for (i = 0; i < size; i++) {
  mae = buf0[i] / 16;
  ctr++;
  usiro = buf0[i] % 16;
  sprintf(mozi, "%X%X", mae, usiro);
  strcat(buf, mozi);
  ctr++;
}
buf[ctr] = '\0';
結果、20KBで、140ミリ秒、100KBで 2813ミリ秒(デバッグモードのデバッグなし開始)





200609
C++のプロジェクト、フォーム

上に新しいメモあり、

C#の速度が、HSPに比べたら早いけど、驚くほどの速さではない、Cに比べたらかなり遅い、という状況でした。
そこで、C++でフォームアプリに挑戦です。
何しろ、プロジェクトの作り方から分かりません。フォームのデザイナが出てこないのです。
ネット参照でようやくたどり着きましたのでメモしておきます。

新しいプロジェクトの作成
上の窓で、C++、Windows、コンソール、を選んでおく。
CLR空のプロジェクト(.NET Framework)を選ぶとビルドが通らない。。
CLRコンソールアプリ(.NET Framework)を選ぶとビルドできる。
次へ
プロジェクト名とフォルダを適当に指定する。
作成
エディタのプロジェクトメニューで、新しい項目の追加、
UI、Windowsフォーム、を選んで、(UIがないのは今までの選択が間違っている)
追加
データが失われる可能性云々のエラーが出る。この場合は、
ファイルメニューで、ソリューションを一旦閉じる
ソリューションの一覧が出るので、今作ったソリューションを開く

何とか、フォームを使う所まで到着して、ボタンをダブルクリックでコードを書き込む場所までは分かりました。
しかし、分かりません。構文が他の言語とはあまりに違いすぎます。
ここで中断(というより放棄)して、DLLを勉強してみます。

そのボタンのコードですが、
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
というものがダブルクリックで生成されます。
ダブルクリック以外に冷静な方法がありそうなものですが、分かりません。

どこか間違っている様です。ビルドしてもフォームが出てきません。main()が?

C#では、同じ部分がこうなっています。
private void button1_Click(object sender, EventArgs e)
この程度だと、我慢して見られます。

どうにもこうにもC++が分かりません。
そこで、C#に戻って、調べました。
文字列の連結に使うStringBuilderクラスというものに気付きました。
これを使うと、C並みとはいきませんが、Cと同じ桁で実行できます。
C#に戻ります。

200609
C#、実行速度
この項、上に、新しいメモあり。

ネットではC#の実行速度は、コンパイラ並ではないにしろ、コンパイラと遜色ないような記事が多いです。
それならと、目下勉強中です。
ある程度、作り上げて、実際に試してみました。結果、HSPよりも少し早い程度です。
いえ、まだ途中経過で、改良の余地がある状況ですし、完全に同じ作業にはなっていないはずです。
とりあえずの結果です。

何しろ、ほとんど文法が分かっていないのに、ネットの文例をつなぎ合わせていくと、動いてしまいます。
そういう作りですので、まだまだ不十分だと思います。

その上で、
20KBのテキストファイルの処理がHSPでは1.7秒でした。

これをC#では、約400ミリ秒、です。
C#の計測結果、debugモードで、(10, 248, 248, 393ミリ秒)、12, 261, 0, 142(合計415ミリ秒)
releaceモードでビルドした実行ファイルで、(11, 183, 183, 319ミリ秒)

やはり、C#でもテキストボックス等へ大量のテキストを表示させると、時間がかかっています。
これはHSPでも同様で、どちらも表示は部分的に省略するようにしています。
どちらも、条件は変わらないと思います。

100KBのテキストで、HSPで40秒でした。
C#の計測結果は、debugモードで:(32, 15541, 15542, 15683ミリ秒)、36, 16006, 0, 155(合計16197ミリ秒)
同、releaceモードでビルドした実行ファイルで:(12, 7953, 7954, 8092ミリ秒)
C#では、8秒という事になります。

ここで、初めてreleace版で生成した実行ファイルで試してみました。
かなり早くなっています。こちらが本当の速さという事でしょう。
Cでも双方試しましたが、差は分かりませんでした。Cでは差が出るほどの作業ではなかったという事かも知れません。

やはり、テキスト表示は部分的に省略しています。
なお、C#で、テキストを省略せずに表示させると、29秒かかります。つまり、ボックスへの表示に13秒かかっています。
上二つ、Cも計測してあります。

まとめると、(前半の作業時間)
言語 20KBのテキストでの作業   100KBのテキストでの作業
処理時間(秒) HSPを1として   処理時間(秒) HSPを1として
HSP 1.703 1.0   39.860 1.0
C#(debug) 0.393 1/4.3   15.683 1/2.5
C#(releace) 0.319 1/5.3   8.092 1/4.9
Cのみ 0.016 1/106   0.078 1/511

HSPと比べればかなり成績が上がりましたが、8秒では心理的にも抵抗があります。
もう少し対策を考えます。

ネットで調べていたら、StringBuilderクラスというものがあって、文字列の連結に強い、そうです。
試しました。
20KBで140ミリ秒、(0, 3, 0, 137、合計140ミリ秒)
100KBで175ミリ秒、(12, 14, 0, 149、合計175ミリ秒)
という結果です。いずれもデバッグモードです、驚きです。
これで、ネットでの評価に近い数字になりました。C++のジャングルをさまよう必要はなく、C#に戻れそうです。


ループについて
この間の作業で、C#でも単純で数の多いループの最中に、帰ってこない状態になることがありました。
フォームの右肩のXのボタンが赤く表示されます。マウスカーソルが行っている状態です。
数秒ですので、何も試していませんが、ちょっとした暴走状態だと思います。
終了だけは出来ます、という意味かも知れません。
HSPではwaitを入れない単純なループでよく経験します。



漢字モード
VSのエディタで漢字がONにならない場合があります。
ビルドしてエラーも結構出ていますので、何やら暴走させているのかもしれません。
エラーが出ている間、デバッグ実行中にはONに出来ないようです。
コードを書き換えられない様にしてあるのかもしれません。



200607
VS、灰色の点々

自己書き換え、とでもいうのかな
VSのエディタに灰色の点々があります。よくできていると思います。
マウスを近づけるとメッセージが出てきます。
int宣言の所で、不必要な代入、とありました。
エラーにはならないけど無駄だという程度なのでしょう。

str.Replace("A", "B")

文字列の一部を入れ換えるのに
str.Replace("A", "B")
というものがあります。
これをそのまま信用して、
str.Replace("A", "B");
と書きます。
いくら待っても書き換わりません。

HSPに同様のコマンド、strrepがあります。
strrep strr,"A","B"、とすると、strrが書き換わります。

C#では、
strr=str.Replace("A", "B");
が正解の様です。

文字コード指定、文字コードの確認
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
System.IO.File.WriteAllText(filePath, htext, enc);

私が扱うテキストファイルの形式は全部Shift_JISなので、苦労しています。
VSではUnicodeが標準みたいですので。
上の構文でファイルのエンコードを指定できるみたいです。
最初に指定しておくと、いい様です。
と言いますのも、ファイル読込の時に指定して、再度書き込みの時に指定するとエラーになります。
例の赤線、インテリセンスが出て、既に定義されているとなります。
コンパイルは通るのかもしれませんが。

さて、問題は実際にShift_JISで保存されているのかが心配です。
構文の意味がよくわからずに使っていますので。
最近は、いい時代になりました。
ネットで探せば、大抵の例文が出ています。
例え初めてのC#でも、面倒な作業でなければ、なんとかなっています。
ですが、上のような心配もします。

そこで、解決策に気付きました。
半角だけのテキストの場合に、文字のエンコードを確認する方法です。
メモ帳ではUTF-8と表示されます。TeraPadでは、Shift_JISと表示されています。
プロパティなどで、バイト数を見ます。
同じもので、エンコードがはっきりしているファイルが必要です。
私の場合は、同じものを、HSPで作っていますので、Shift_JISとはっきりしているものがあります。
それと同じバイト数ならShift_JIS、少し大きいならUTF-8となります。

上のメモは、BOM無しUTF-8だとダメみたいです。
しかし、VSで出力されているものはBOM有りでした。

検索と置換、インテリセンス
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
System.IO.File.WriteAllText(filePath, htext, enc);

上のコードのencをShiftJISencに置換したいと考えました。
ネットを見ていたら、同じような文例を見つけ、こちらの方が分かり易いなと思った次第です。
それに、多分、この単語は適当に変えていい部分だと気が付きました。

で、エディタの編集メニューにある検索と置換から実行しようとしました。
すると、encの部分は良いのですが、どうやら.Encoding.GetEncodingにあるEncの部分も置換対象に含まれている様子です。

そこで、いちいちスキップする方法はありますが、手間は変わりません、手書きで変更していくことにしました。
手書きと言っても最初にShiftJISencをコピーしておいて、対象のencを探してペーストしていきます。

ここで、ありがたい機能に気付きました。
よく出てくるインテリセンスの赤い点線です。これがとても役に立ちます。
最初に、定義の?最初の行の、encを書き換えると、残りのencが全部赤い点線になっています。
先ほど度違って、今度は変更が必要な部分だけです。
これを順番にペーストしていくだけでした。



200605
C#、ツールボックス
フォームを作るのに、C#が簡単という記事を見て、ちょっと始めてみました。
VSにC#も全部入っています。多分。
見よう見まねで作っていきます。
ネットからの切り貼りで何とかなるというのが、便利というか恐ろしいというか。

確かにフォームデザインが簡単にできます。できました。
それでもやはり試行錯誤です。
失敗した時、意図通り出来上がらない時、フォルダーごと削処して、プロジェクトの作成からやり直しです。
いえ、どこが間違っているのか分かりませんし、修正なんかできるはずもありませんので。

何回かやり直しているうち、ツールボックスからボタンbuttonという項目がなくなりました。
新しいプロジェクトを作る際、.NETCoreと.NETFrameworkを行き来している時でした。
フォームにボタンが貼り付けられません。
困って、色々メニューを探したら、それらしきものがありました。ツールボックスのリセット、という項目です。
ツールボックスの上での右クリックメニューです。
これで復活しました。

長い文章を表示するボックスをつくるのに、TextBoxだと一行しか表示できそうにありません。
試してみると、よさそうな物に、RichTextBoxがありました。
これだと、簡単に、縦長のボックスが作れます。
しかし、よくよく調べると、TextBoxでもよかった様です。オプションでMultlineをセットすると縦に拡張できました。
今のところ、どちらが正解なのかは分かりません。

TextBoxにも最大文字数があるようです。32KBみたいです。
ただ、こちらはプロパティで簡単に変更できるとの事です。

さて、迷いごとを一つ、
System.IO.File.Exists();、
という構文と、

using System.IO;
.IO.File.Exists();
という、どうやら二つが分離されている構文があります。

どうやらusingがdefineみたいなものの様で、以下省略できるという意味の様です。
迷いますね、統一してもらいたい所です。


200529
文字列の比較

Cで文字列の比較で躓きました。
if (argv[1] == "ag")です。全く意図通り動いてくれません。

試しに、
printf("1番目の引数は:%s %d\n",argv[1],strlen(argv[1]));とすると、
ちゃんと
1番目の引数は:ag 2、とでます

正解は、Cでは文字列の比較は、==、では意味がなく、
if (strcmp(argv[1], "ag") == 0)
だそうです。

思い起こせば、HSPでも同じような事情があります。ただHSPでは=までは通じます。
大小の比較はできません。



200528
CTRL+A

各種編集作業の時便利なキーがあります。
Ctrl+C、Ctrl+V、Ctrl+X、Ctrl+A、です。
コピー関係のショートカットです。
特にCtrl+Aは重宝しています。全て選択、ですね。

私は、HSPの作業中に途中の経過をクリップボードに転送しておきます。
メモ帳などに貼り付けるのです。
作業後にそれを見て、意図通り動いているか調べます。

この時、前回の経過が貼り付けてあるメモ帳の表示を入れ換えるのに、Ctrl+A、Ctrl+Vで済みます。
ただ、最近、これらのショートカットを多用していると、効かなくなることがあります。
コピーもペーストも出来なくなります。

原因不明です。特に、HSPのエディタ上で顕著です。HSPを再起動すると回復します。
最近、Cを始めたので、何か悪影響が出ているのかもしれません。
そのものずばりで、clipsetを多用している事が原因かもしれません。


200524
VSのエディタ、赤い波線、インテリセンス
VSのエディタでCの作業中、全く関係ないファイルから数行のテキストををコピーして持って来ました。
すると、赤い波線が出て来ました。理由はよくわかりませんが、エラーの様です。
赤い波線は、例えば、行末にセミコロン;、を付け忘れた時に出てきます。心穏やかではありません。
どうやら、この波線をインテリセンス、というみたいです。やはりエラーです。

しかしながら、コピーしたものは日本語のテキストで、貼り付け(ぺースト)した場所は、/**/で囲んだ注釈行の中なのです。
構文の間違いではありません。
200526追記
この件、プログラムをVer16.6.0へアップデートする事で解決しました。した様に見えます。
以下、無意味なドタバタの記録です。200609再発しました。
まず、VSで悩まされている、日本語コードを疑いました。
調べてみると、ファイルの日本語コードは、コピー元もコピー先もShift_JISです。
コピー先の、VSのC言語のソースも、何故かShift_JISなのです。
VSのエディタで、どのように扱っているかは調べようがありませんが、保存してあるソースファイルはShift_JISです。

試しに、保存してあるソースファイルをメモ帳で開いて、同じ内容を貼り付けて、VSを立ち上げてみました。
結果、同様に赤い波線が出てきます。

特殊な漢字を使っていて、それに反応しているのかもと調べてみました。
昔、機種依存文字とか、コントロールコードとかの絡みで、こういう事がありました。
一行ずつ、一文字ずつ削除して調べました。それでもはっきりしません。
消える場合もあります。消えない場合もあるのです。どの漢字か特定できません。
しかも、全部削除しても波線が残る時もあります。

ただ、コンパイル、ビルドは通ります。
この用語がよく分かりません。
昔は、実行ファイルを作る作業をコンパイルとかリンク、メイクmakeとか読んでいたと思いますが、VSには、今の所、どちらも出てきません。
後日、調べて、実行ファイルを作るのはビルドだそうです。いつもビルドした後デバッグしていたので、デバッグで実行ファイルが作られるのかと勘違いしていました。
更に、releaseモードでビルドしたものが正式の実行ファイルの様です。
debugモードでもビルとすると実行ファイルができます。
同じものかと思っていましたが、ファイルを比較しててみたら。サイズが違います。
releaseモードの方が小さくなっています。
どこにも書いてありませんが(どこにも見つけられませんが)、多分、デバッグモードの方は、デバッグの為のコードが含まれているのでしょうね。暴走しない様に。
実行速度にも違いがあります。releaceの方が早いです。

そのビルドやデバッグですが、波線があってもできます。実行できています。
これはやはり、波線の方が間違いだろうと考えるようにもなりました。

ある時、偶然気付きました。
窓で作業している時に発生します。
全画面で作業している時はこの現象は出てきません。
ただ、窓で発生している状態で、全画面にしても消えません。
逆に、全画面でコピーして、窓に変えた場合は、発生する場合も発生しない場合もあります。
困ったものです。
貼り付けたものを、元に戻すコマンドで戻しても消えない事が多いです。しかし、そのまま全画面にして、赤線の出た状態で終了して、再度起動すると消えていたりします。
色々試すと、もう滅茶苦茶です。

プロジェクトをもう一つ作ってあって、そちらではこの現象は発生しません。
そこで、考えました。
最初からやり直す事にしました。
下のメモにある方法で、既存のCファイルからプロジェクトを作り直してみました。
何しろ、ソースファイル一つのプロジェクトです。
そのファイルを一つだけコピーして作り直すだけです。
これで見事解消しました。

思うに、原因は、
この作業中にソースファイルを入れ換えたことです。
なんの為だったかおぼろげですが、どこかのコメント行を追加したか、コードの一部を他所から持って来たかで、ソースファイルを同じ名前で入れ換えたことがあります。
多分、このせいだと思います。
試してみると簡単に分かることですが、面倒なのでやりません。
VSのプロジェクトは、多数のファイルが出来ています。
その中に、何かエディタ上の変更に付随して書き換わるファイルがあるのではないだろうか、という事です。
VS以外のエディタで、途中で編集をすると、何か辻褄の合わない事が起きるのではないのか、というのが、現在の推定です。

200526追記
再発しました。また赤い波線です。
思い当たる直前の作業は、
まず、ちょっと暴走気味で、メニューの変な所をクリックして、帰ってきませんでした。
どうするかのダイアログが出て、終了を選びました。
メモ帳からの文章をコピーで持って来ました。
#define文で、一行に//を2か所使いました。
この辺りで波線に気付きました。
やはり、窓での作業中でした。全画面にすると、消える時も消えない時もあります。
今回は、二つのプロジェクトで同時に発生しました。

行き詰って、最後に、プログラムのバージョンアップが無いか調べたら、新しいものがありました。
更新しました。
今の所、発生していません。波線は出ていません。まだアップして一日目ですが、平穏です。

200609
再発しました。
コメントの、/*、*/、の部分が赤い波線になっています。
今回は、変な作業はしていません。いえ、他のテキストからコピペぐらいはしたかもしれません。
200610
また、更新がありましたので、実行しました。Ver16.6.2になっています。
再起動したら、消えています。
200616
しばらく出ていませんでしたが、今日出ました。赤い波線です。
何故か、ほぼ全体的に発生しました。
終了、起動を何度か繰り返すと消えました。
発生は、エラーと言いますか、例外が発生した直後に出るようです。
一旦VSを終了し、再開すると大体は消えます。
更新は関係ないかも。更新したら、再起動しますからね。
こんなものなのかも知れません。



200522
既存のCのファイルからVSのプロジェクトを作る

既存のC言語のコードからVisualStudioのプロジェクトを作る段取り。
これまで、何度か試していて、ここまで、うまく行ったり行かなかったりでした。
今日、改めて試して、すんなり成功しましたので、メモしておきます。

別のプロジェクトで使ったフォルダ全体をコピーして、フォルダとソースファイル名だけ変えて、新しいプロジェクトを立ち上げても、うまく行きませんでした。対策を知らないだけかもしれませんが。
ソースファイルだけを、名前を変えて新しいフォルダにコピーして、この方法でプロジェクトを作るとうまく行きます。
(単独のソースの場合です。)

まず、
VSの起動画面の、プロジェクトの選択画面で、コード無しで実行、を選択します。

何も無い状態でVSが開くので、
メニューの、ファイル、新規作成、既存のコードからプロジェクトを作成、を選択していきます。

作成ウイザードが開くので、
作成するプロジェクトの種類はVisualC++、を選択し、次へのボタン、

プロジェクトのファイルの場所は、あらかじめ準備していたフォルダを、
プロジェクト名は、準備してある既存のCのコードのファイル名を入れます。
ここ、あらかじめ、既存のファイル名、フォルダ名、プロジェクト名の3つを同じ名前に合わせています。ただ、これが必須かどうかは不明です。
この窓には、都合3個のチェックボックスがあります。
一つは、次のフィルダー云々「フィルダー」となっています。
既定で全部チェックされていますので、そのままです。意味は分かりません。
次へのボタン、です。

つぎの画面で、プロジェクトの種類に、コンソールアプリケーションプロジェクト、を選択します。
ここの選択肢で、Windowsアプリケーションが既定の様ですが、多分、これを選ぶとまずいのだと思います。
後、次へのボタンで数画面ありますが、意味不明で、いずれも既定のままです。
ですので、完了ボタンで終わっています。

この設定で始めると、先のSDL関連はチェックされていません。
ですので、最初から、ビルドエラーは出ません。


200522
VSでコードのファイルがリソースファイルのフォルダに属している

何やら、試行錯誤でプロジェクトを作った際、よく見ると、Cのソースファイルが、ソリューションエクスプローラーでリソースファイルのフォルダに属している問題。

ファイル一つのプロジェクトで、ソースファイルのフォルダには何もありません。
これで、期待通りに実行は出来ているので、実用上の問題はないのですが、少し不安です。

そこで、思い切って入れ換えてみました。
方法は、
ソリューションエクスプローラーのファイル名の右クリックメニューに削除という項目があります。
これを選ぶと、除外か削除か選択するように促されます。
そこで、除外を選びます。削除を選ぶと、実際にファイルが削除されそうでした。
次に、ソースファイルの右クリックメニューで、追加、既存の項目、と進んで、該当ファイルを選択すると、無事入れ換えが出来ました。
ビルドもデバッグも同じようにできます。変わりません。


200521
VS2019、ビルドエラー、C4996

これまで、ほどほどうまくいって、期待通りの結果を出しているCのプロジェクトがあったので、このコードを使って別のファイルを作ろうと、新しいプロジェクトを立ち上げました。

新しいプロジェクトを作り時、試行錯誤で色々試したので、どの方法だったか思い出せません。
何やら、ソースファイルに、元のファイルからコードを全コピーして持ってきたと思います。
ところが、全く同じコードなのですが、ビルドエラーです。
fopenなどがエラーになっています。
元のコードでは警告で済んでいる所です。

何か対策があるはずと調べてみたら、
ソースファイルを反転させて、(右クリックメニューにあるプロジェクトから進んでも同じです。)、
メニューの、プロジェクト、プロパティ、C/C++、全般、と進んで、SDLチェック、という項目を、いいえ、にすると解決しました。
プロジェクトの作り方、初期設定が間違っていたのだと思います。
多分、コンソールではなくWindowアプリを選んでいたのだと思います。

なお、この問題、上の200522の記事で、根本的な(多分)解決方法を見つけてあります。

200519
malloc

Cでテキストファイルを読み込もうとしました。
250KBほどある巨大なファイルです。
大きいファイルだと、読み込んだり、作業するのが面倒なので、最初は小さなファイルから始めました。

まあ一応、予定通りの動きをします。
そこで、目的のファイルを読み込ませてみます。
エラーです。

試行錯誤と合わせて、ネットで調べた結果、分かったことです。
文字型配列の要素数に限度があり、大きな配列を宣言する時は、mallocを使って領域を確保する必要があるとの事です。
スタック領域、ヒープ領域という言葉で説明されています。
普通の宣言では、スタック領域に確保され、こちらだと、通常、あまり大きな領域は確保できない。
思い起こすと、アセンブラで言う、push、popの領域でしょうかね。
ヒープ領域は、この制限がなく、こちらを使う時には、mallocを使って確保する、のだそうです。

200512
文字コード、改行
Cでのテキストファイルの保存に関して
改行が余分に入って保存された事があります。
メモ帳で見たら、Macintosh(CR)となっていました。
TeraPadでは、SJIS CRと表示され、やはり改行が余分に入っていました。
ワードパッドでも試しました。改行されていませんでした。こちらでは何と判断されているか分かりませんでした。

余分な改行の原因はすぐ分かりました。と言っても試行錯誤の結果です。
fopenを "w"で開くと別にCRが付加されます。CRLFの他にCRが付きます。
"wb"で開くと、そのままです。
そうです。テキストをバイト単位で扱っているプログラムです。
ですので、16進のダンプも打ち出せます。
先の改行を挟む所は、通常は0d,0a、(CR,LF)となるべきところで、
余分な改行が入っている分は、0d,0d,0a、(CR,CR,LF)となっていました。
読込の時は、普通に"r"でfopenしても問題は出ていません。

なんとなく、世間では常識的な話なのかもしれません。

200512
プログラム言語、VisualStudio2019、文字コード

ほかの言語についても、多少の知識はあります。あるつもりでした。
現に、PCには古いコードを残しています。
1998年にCを、2003年にC++をやっていた形跡があります。LccとかBccとかのフォルダがあります。
コードもexeファイルも残っているので、試しに実行してみましたが、現在の環境では動きませんでした。
タイムスタンプから見て、Win98とかXPの頃でしょうかね。XPの環境はありますので、実行してみましたが、動きませんでした。

PCを作り変える際、データディスクだけは、そのまま付け換えるなり、コピーするなりして移動させていましたので、当時のOSが何だったかは、はっきりとは思い出せません。

他に、COBOLを勉強していた時期があります。
かすかな記憶では、COBOLは計算が苦手で、平方根の計算が出来ませんでした。
そこで、ニュートン法を使って試行錯誤で平方根を探すルーチンを作った覚えがあります。

具体的には、平方根は、元の数字以下になる事は分かっていますので、まず、元の数の半分の値を2乗します。
さすがに2乗は掛け算です。どの言語でもできます。
この結果が、元の数より大きければ、更に下半分に答えがあることが分かります。
小さければ、上半分です。
ですので、どちらかをさらに半分にした数字で試していきます。
これを必要な桁数まで探していくだけです。
これをある程度進めていくと、小数点以下で変化しない桁が増えていきます。
その変化しない桁は有効な数字と考えていいはずです。多分。

このルーチンは、当時は貴重だったのかもしれません。
オフィスコンピュータのメーカーのSEの方から、コピーさせてくれと頼まれて、コードの入っているFDを渡した記憶があります。
何しろ、当時、COBOLはオフコンでのみ動いていましたので、コンパイルさせてもらう為に、時々、メーカーの事務所に遊びに行っていました。会社にオフコンを導入した際の取引先でした。

BASICに関しては、使っていたPCの数だけありますね。
当時は、各メーカーが独自のパソコンを作っていて、OSもメーカーの数だけありました。それぞれ、ほとんど互換性はありませんでした。
その後、MS-DOSというOSが主流になって、全てMSのWindowsに流れていく訳です。

思い出すのは、沖BasicとN88Basicとの共通のFDを作った事です。
当時は5インチFDでした。2DDとか1MとかのFDの頃です。
双方のBasicで、FATでしたか、データを管理する領域の配置が違っていました。
幸い、当時は、セクター単位で読み書きするコマンドがBASICにもあって、自由に中身を調べ、変更できました。
そこで、互いの管理領域に仮のデータがあるように処理して、アクセスしないようにしていました。

アセンブラも少し勉強しました。MASMとかありました。
当時、Z80でした。haltだけ覚えています。
こちらは、8086に変わった時点で諦めました。
逆だったかもしれません。
ニーモニックでしたか、命令語が一段と増えていました。まあ、様子見、冷やかしでしたので。

さて、本題は、
とにかく、処理の早い言語の導入を考えました。
どうやら、コンパイラならどれでもいいようです。
各言語での速度比較のページによると、BASIC関係以外は大差ありません。いえ、BASICやHSPに比べたら格段に速いです。

真っ先にC言語です。
以前、Cで簡単な計算をする物を作っています。
最初、LotusかExselのシートで作った物を、Basicに移し、C言語に移しました。
更に主流は当時でもC++に移行中で、C++でも作りました。
ところが、C++に至って、クラスだったか構造体だったかが理解できず、挫折しました。
おぼろげな記憶ですが、とにかく、選択肢が多くて、複雑で面倒だなと思ったものです。
その後、現在のHSPを見つけて、ほとんどこれ一本で遊んでいます。
数KBのファイルを扱うものなら、インタプリタでも速度が遅くても問題ないのです。

ここに至って、なにがしかのコンパイラで作ればなんとかかるだろうと、準備を始めました。
VisualStudio2019をインストールしました。
これだと、CでもC++でもVisualBasicでも使えるという事です。しかも無料です。
先の速度比較では、VisualBasicでもHSPより格段に速いとありました。

まず、VB、C++,、Cと試しました。
先に、昔、自分で作った物をVS2019に移そうとしましたが、まずこれが出来ません。
ようやく移行できて、コンパイルすると、ビルドでしょうか、エラーです。
残念なことに、Cでさえ、その原因が分かりません。
どうやら、当時のコンパイラ独特のヘッダファイルとかがあるようです。

それなら、VBなら何とかなるかと、試してみました。
さすがに、VBだと、ある程度工夫すると動きます。
ところが、結果が文字化けします。
理由は、どうやら昔のShift_JISが通用しない事にあるようです。
いまのVisualStudioはUnicode(UTF-8、16)が標準みたいです。
コンバートする方法もあるみたいですが、理解できません。うまくいきません。

最終的にCで組めました。コンソールタイプですが。
ありがたいのは、どうやらC言語だとVSでもShift_JISで扱える事です。
標準なのかどうかは不明ですが、そのままで通用しています。
ソースファイルもShift_JISで保存されています。
ことによると、最初の既存のコードファイルがShift_JISだったので、そのまま引き継がれているのかもしれません。
作業対象のShift_JISのテキストファイルを普通にfopen、fread、fwriteすると、Shift_JISのままで操作できています。



200512
実行速度
現在、このサイトのページを作る事以外にも、色々な作業をHSPで試しています。
その中で、テキストファイルの変換をするものを作りました。
テキストを読み込んで、変換作業をして、再度ファイルに保存するものです。
単純な作業なのですが、バイト単位の作業で、意外と時間がかかります。
100KB程度のファイルで、11分ほどかかっていました。(この点、下に訂正あり。)
これでは、少し、時間がかかり過ぎです。

そこで、他の言語の実行速度を調べてみました。
まず最初に、自分のスクリプトを見直してみる、という事には思い当たりませんでした。
ネットで、他の言語を調べてみると、さすがにコンパイラでは速度は桁違いです。しかも何桁も違います。
そこで、コンパイラを試す事にしました。

200526追記
C言語での作業が一段落したので、結果です。
対象は100KB程度のテキストの変換作業です。作業内容は先のHSPと同じです。
HSPのみでは、11分かかる作業が、Cで作ると、125ミリ秒弱で終わります。0.125秒です。
HSPに比べてCでは、1/5500の時間で済んでしまうという事になります。(この点、以下に訂正あり。)

200530追記
Cでコードを作る際、HSPで組んでいたスクリプトを参考にしました。
ここで、HSPのアルゴリズムを見直しましたので、実行速度に関して、ものすごく冗長に作っていた事に気付きました。
プログラムは、速度より見やすさ優先が昔からの癖で、一回のループで済むところを何回かに分けたりして処理しています。

極端な話、数回のループなら、スクリプトをその数分コピーして済ますようなこともあります。
この方が、安全確実ですので。

やむを得ず、ループ内で複数の作業をする場合、作業の経過が分かるように、中間の処理状況を入れる変数をたくさん作ります。
途中、debugやassertを使って状況を調べられ、作業状況が分かり易くなるのは間違いありません。
ただ、大量のデータを扱う場合、そうも言っておられません。上の通り、たいした事をしていないのに11分かかる様になってしまいます。

Cの方は、アルゴリズムが分かっていたので、一回のループで処理できています。
それに、経過記録など悠長なコードの書き方を知りません、コンソールなので元々表示が単純でした、等が原因でしょう。
時間計測の際は、更に、#defineでprintf類をスキップします。

これを見習って、翻って、今度はHSPのスクリプトも修正しました。
作業時間の比較をするのなら、無駄な作業を省かないといけません。
無駄な変数を使わない。
無駄な表示もしない。
今回、mesboxも大量のテキストだと、表示時間が結構かかる事に気付きました。
しかも、末尾の記述が見やすいように、逐一スクロールさせていましたので大変です。
また、mesboxを使って、バイト単位の作業状況を表示させていました。
つまり、バイトごとに表示、ここでは数字ですが、を書き換えていました。
ループも出来るだけ少なく、中でawait類を使わない。(これで大量のデータ処理をすると、帰ってこない状態になりますが。)
等、作り直しました。

結果、先の100KBのテキストの処理が、49秒で終わるようになりました。HSPだけでの作業です。
上で、冗長なスクリプトで、11分かかったとメモしたものです。正確には689秒でした。
HSPでの改良だけで、前に比べて、1/14の時間に短縮されています。
いえ、それだけ冗長なスクリプトを書いていた、という事で、11分に関しては、これ以上比較する意味がありません。

次に、肝心のテキストの変換作業だけをCで代行する事を考えました。
本来は、作業速度を考えるなら、デスクトップを含んで全部をCか他のコンパイラで作ってしまう所でしょう。
あるいは、Cでdllを作って、HSPで読み込んで実行させる、という事の様です。
これについても少し調べましたが、私にはどちらも理解が出来ませんでした。

そこで、Cとの連携をファイルを使ってする事にしました。幼稚なやり方です。ですが、今の知識で出来ました。
目的のファイル名など、HSPでデータ引き継ぎ用のテキストファイルを作って保存して、Cを呼び出します。
Cでは、そのファイルを読み込んで変換作業をし、作業結果を、やはりファイルに保存します。

まあ、Cでも、ファイルの読み書きと、足し算引き算ぐらいなら、私にも出来るという事です。
それに、今回分かった事で、ファイルの読み書きには、さして時間がかからないという事です。
Cと引継ぎをする為のファイルにしろ、作業対象のファイルにしろ、ミリ秒の単位で処理されています。

このCで作るファイルをHSPで見張っていて、ファイルが出現したら、作業完了となります。
今、HSP側で、ファイルの出現を見張る間隔を1秒にして試すと、変換作業が3秒で終わるようになりました。
HSPだけで作業すると、50秒でしたので、1/17に短縮したことになります。
何より、3秒程度の待ち時間なら、精神的に許される時間だと思います。
その意味で、Cとの原始的な連携は許されていいと思います。

更に、HSP側の見張る間隔を0.5秒にすると、作業は1.2秒で終わりました。
これなら、もう十分に許される範囲です。
改良しても、HSPだと目的の100KBを処理するのに50秒かかります・
これでは、やはりストレスです。Cと組み合わせた価値が出てきます。

この状態で、C単独での実行時間(0.094秒)と比べると、527倍の時間です。Cだと、1/527の時間で済む、という事です。

ここまでの数字を一覧表にまとめてみます。
言語 100KBのテキストでの作業   20KBのテキストでの作業   2KB のテキスト
処理時間(秒) HSPを1として   処理時間(秒) HSPを1として   処理時間(秒) HSPを1として
HSP改良前 689.000 13.9   134.000 60.2  
HSP改良後 49.548 1.0   2.226 1.0   0.156 1
HSP+C 1.234 1/40   1.023 1/2.2   1.094 7.0
Cのみ 0.094 1/527   0.031 1/72  

20KBのテキストでも試してみました。
HSP+Cでの作業時間は、どちらでも、ほとんど変わりません。
これは、HSPでCの作業終了を見張る間隔を0.5秒にしている事で、この時間内に収まる作業では差は出ないという事でしょう。
何しろ、C単独だと、0.1秒程度で終わっています。

HSP単独での作業で、作業時間がファイル容量の比率にならないのが不思議です。
指数関数的な作業になっている様ですが、よく分かりません。

HSPで、2KBも試して、HSPだけで時間の比較をしてみました。
100KBだと、1KB当たり、0.495秒、
20KBだと、1KB当たり、0.113秒、
2KBだと、1KB当たり、0.078秒、
やはり、何か指数関数的なものがあるようです。



200507
Visual Studio Code 日本語化

エディタが欲しくて、Visual Studio Codeをインストールしてみました。
HSP以外のプログラム言語に挑戦してみようという魂胆です。
どうやら、今持っているTeraPadやメモ帳では物足りないみたいですので。

まず最初に、
MSのページからインストーラをダウンロードするのですが、紹介されているページが沢山あり、どれが一番安全なのか、主流なのか迷います。
結局、Microsoft Storeにも置いてありましたので、これを使いました。
他にも、MSのページが検索の最初に出ました。そこからもダウンロードしてみましたが、全く同じ物でした。

インストールは簡単に終わり、簡単に起動できました。
途中、デスクトップにアイコンを作る、ファイルの右クリックメニューに追加する、という意味のチェックが出ましたので、追加しておきました。

問題は、最初の起動が英語で、これを日本語化する事でした。
ネットの記事通り実行したつもりですが、再起動しても相変わらず英語のままです。

何度か試した結果、原因は、
メニューのviewのプルダウンから幾つか進んで、
configure display languageをクリックした後、
select display languageというダイアログが出ますので、
そこで、jaを選択する、
という事でした。
この間、日本語のインストールが済んでいなければ、その作業も入ります。

肝心の場面は下のキャプチャー画像の通りです。
そのまま適当にクリックしたり、Enterなどで指定するとenの方が反転していて、enを指定したことになります。
ここでしっかり、jaの部分を指定し、反転させねばなりません。
install云々の所をクリックしても、jaを選択したことにはなりません。
enを選択した状態でも、再起動のメッセージが出ますので、ここがとても迷うところでした。


200506
HSP、C言語

普段、HSPでプログラムを作っています。趣味程度です。
このサイトの大半のページを、そのHSPで半自動化しています。
今回、サイト作成とは関係なく、テキストファイルを読み込んで、バイト単位で変換して、保存する、というプログラムを作りました。
ところが、これが手間取るのです。
100KB程度のテキストファイルだと11分かかってしまいました。

このサイトのページは、5KBから10KB程度です。この程度のものだと待ち時間は感じられません。
ただ、11分もかかるようだと問題です。
対策は、プログラムを改良するか、他の言語を試すかです。
他の言語を試すことにしました。



トップページへ