ブログを検索

2024/06/21

LRA1 BASIC で気になったことや処理速度実験

 気になったのでメモ

「その1」はプログラムの書き方によっては受信データロストに繋がるという件

気付いた都度追記していく

その1 知らずにデータをロストしていた orz

下記プログラムで150行目で Stat=10のときがある。
タイミングでそうなるということは別の考え方をするとStatを確認したら速やかにStat=0をセットしないとデータをロストする確率が高まる。しかもロストしていることに気付かない。ここは行数をケチったりコードの見た目を綺麗にするのは考えないようにする

発生頻度

送信側は5分毎送信。受信側は RECV 0 で常に受信待ち受け、100msec毎受信データ有無を確認している状態
1時間で12回受信のうち4回がこのタイミングになった。結構な頻度でロストしていた 汗

受信プログラム
10 RxStop:Stat=0
20 Recv 0
100 Do
110   If Stat=10 Then
120     Stat=0
130     Print Rxd
140   Else
150     ' ここでstat=10のときがある
160     If Stat!=0 Then
170       Print "Error Stat=";Stat
180     EndIf
190     Stat=0
200   EndIf
210   Delay 100
999 Loop

なので下記のように 190行目削除。160行目~170行目修正と追加
10 RxStop:Stat=0
20 Recv 0
100 Do
110   If Stat=10 Then
120     Stat=0
130     Print Rxd
140   Else
150     ' ここでstat=10のときがある
160     If Stat!=0 && Stat!=10 Then
165       S=Stat:Stat=0
170       Print "Error Stat=";S
180     EndIf
190     Stat=0
200   EndIf
210   Delay 100
999 Loop

その2 ループ方法やコメント有無の処理速度への影響


BASICインタプリタ全盛の1980年代前半にやってたような簡易テストをしました。
ワタクシ当時は中学~高校生 遠い目
下記コードで簡易的に試した結果をまとめると

・ループ方法は For Next が一番速い Step有無は影響なし。ただし無限ループとしての Do Loop や Goto は不明。exit条件のIf文を入れるとFor Nextより遅い事だけ判った
・コメント行があると遅くなる
・コメント行はコメント文字列が長いと遅くなる
・I=I+1 より I++ のインクリメントが速い
・マルチステートメントは遅くなる
・ラベル名が長いと遅くなる
問題点を挙げてるわけじゃなくBASICプログラム書くときの目安としてテキトーに実験してみた
プログラムエリアの消費量との兼ね合いがあると思うのでマルチステートメントは使うところは使う
分かりやすさとの兼ね合いでラベル名も最低限の長さはとる
結論は実験結果を参考にしつつもそもそも処理速度は求めていないので書きやすいように書けばいいだけかな

■For Next これが基準 所要時間19秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 For I=0 To 100000 Step 1
140   I=I+1
150   J=J+1
160   'NOP
170 Next
180 Print "20"; Datetime (Clock);".";Milisec

■Step省略 効果なし 所要時間19秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 For I=0 To 100000
140   I=I+1
150   J=J+1
160   'NOP
170 Next
180 Print "20"; Datetime (Clock);".";Milisec

■インクリメント 効果あり 所要時間14秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 For I=0 To 100000
140   I++
150   J++
160   'NOP
170 Next
180 Print "20"; Datetime (Clock);".";Milisec

■コメント行増 逆効果あり 所要時間45秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 For I=0 To 100000
140   I++
150   J++
160   'NOP
161   'NOP
162   'NOP
163   'NOP
164   'NOP
165   'NOP
166   'NOP
167   'NOP
168   'NOP
169   'NOP
170 Next
180 Print "20"; Datetime (Clock);".";Milisec

■すべてのコメント削除 効果あり 所要時間11秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 For I=0 To 100000
140   I++
150   J++
170 Next
180 Print "20"; Datetime (Clock);".";Milisec

■コメント1件 「■インクリメント 効果あり」の再掲 所要時間15秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 For I=0 To 100000
140   I++
150   J++
160   'NOP
170 Next
180 Print "20"; Datetime (Clock);".";Milisec

■コメント長増 逆効果あり 所要時間19秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 For I=0 To 100000
140   I++
150   J++
160   'NOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOPNOP
170 Next
180 Print "20"; Datetime (Clock);".";Milisec

■マルチステートメント 逆効果あり 所要時間18秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 For I=0 To 100000
140   I++:J++
160   'NOP
170 Next
180 Print "20"; Datetime (Clock);".";Milisec

■For Next から While Loopへ変更 逆効果あり 所要時間38秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 While (I<=100000)
140   I++:J++
160   'NOP
170 Loop
180 Print "20"; Datetime (Clock);".";Milisec

■while LoopからDO~LOOP WHILE へ変更 逆効果あり 所要時間52秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 Do
140   I++:J++
160   'NOP
170 Loop While (I<=100000)
180 Print "20"; Datetime (Clock);".";Milisec

■ForからDo If exitへ変更  逆効果あり 所要時間45
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 Do
135   If I=100000 then exit endif
140   I++:J++
160   'NOP
170 Loop
180 Print "20"; Datetime (Clock);".";Milisec

■Do If exit から goto If End へ変更  逆効果あり 所要時間61秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 _looppoint
135   If I=100000 then Print "20"; Datetime (Clock);".";Milisec::End endif
140   I++:J++
160   'NOP
170 Goto _looppoint
180 Print "20"; Datetime (Clock);".";Milisec

■ラベル文字列長増  逆効果あり 所要時間147秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 _looppoint_looppoint_looppoint_looppoint_looppoint_looppoint_looppoint_looppoint_looppoint_looppoint
135   If I=100000 then Print "20"; Datetime (Clock);".";Milisec::End endif
140   I++:J++
160   'NOP
170 Goto _looppoint_looppoint_looppoint_looppoint_looppoint_looppoint_looppoint_looppoint_looppoint_looppoint
180 Print "20"; Datetime (Clock);".";Milisec

■ラベル文字列長短 効果あり 所要時間53秒
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 _l
135   If I=100000 then Print "20"; Datetime (Clock);".";Milisec::End endif
140   I++:J++
160   'NOP
170 Goto _l
180 Print "20"; Datetime (Clock);".";Milisec


おまけ実験 ループの中で For Next が一番速いなら・・・
■For Nextで無限ループ
100 Print "20"; Datetime (Clock);".";Milisec
110 RxStop
120 I=0:J=0
130 For I=1 To 2
140   I=1
170 Next
180 Print "20"; Datetime (Clock);".";Milisec




0 件のコメント:

コメントを投稿

MySQL で SELECT into outfile 出来なくてハマった件

 Windows上の MySQL で SELECT into outfile で CSVファイルをエクスポートしようとしてハマったので残しておく 環境 Windows10 Pro バージョン 1809 MySQL 8.4.0 という環境で SELECT * FROM table1...