JRA公式競馬データ配信サービス JRA-VAN Data Lab.

JRA-VAN DataLab.

競馬ソフト開発コーナー

JV-Link 質問箱

一括表示 リストに戻る
タイトルC#でのメモリ解放
記事No6853
投稿日: 2022/02/23(Wed) 08:33
投稿者たかひろ
JRA-VANソフトサポート様

C#にて蓄積系データの取得を行うプログラムを作成したところ
データの取得量と同じ量で使用メモリが増えていく現象が発生しております。
JVGetsのリファレンスに書かれているVBコードでのEraseに相当する何かが足り
ていないかと思うのですが
C#ではどういった記述をすればよいかご教授いただけないでしょうか。

ソースコードは下記になります。
https://harigami.net/cd?hsh=d5fb4117-0123-4746-a1e3-749f96f1a140

また、JVReadにて読み込みを行うと下記のエラーが出るのですが、こちらも併
せてご教授いただけないでしょうか。
こちらについては過去投稿の6752と同様のエラーだと思うのですが、過去投稿
に対処方法として書かれている引数に値を設定しても改善しませんでした。
---
Unhandled exception. System.Runtime.InteropServices.COMException (0x800
10105): サーバーによって例外が返されました。 (0x80010105 (RPC_E_SERVERFA
ULT))
---

タイトルRe: C#でのメモリ解放
記事No6854
投稿日: 2022/02/23(Wed) 08:35
投稿者たかひろ
過去ログに合った確認項目については下記になります
> @どのデータを取得しようとしているか
2006年のデータになります。ただ取得範囲には依存していないように思います

JVOpenの引数だと"20060101000000-20070101000000"です。

>A実行ユーザの権限
管理者/一般ユーザともに発生します。

>Bウィルス・セキュリティソフトを停止し、実行してみて同様の事象が発
生するか
セキュリティソフトを停止した状態でも、メモリリーク、サーバエラー共に発
生します。


環境:
Windows 10 Pro
Microsoft Visual Studio Community 2019

使用言語: C#
フレームワーク: .NET 5.0

JRA-VAN SDKバージョン: 4.7.0

以上、よろしくお願い致します。

タイトルRe: C#でのメモリ解放
記事No6867
投稿日: 2022/02/27(Sun) 16:22
投稿者Tachyon
JVReadについては、エントリーポイントにSTAThread属性を適用すれば解決しま
す。

[STAThread] ←追加
static void Main(string[] args)
{

ご参考まで。

タイトルRe^2: C#でのメモリ解放
記事No6870
投稿日: 2022/02/27(Sun) 18:10
投稿者たかひろ
Tachyon様

JVReadが正常に動くようになりました!
情報ありがとうございます!m(_ _)m

タイトルRe: C#でのメモリ解放
記事No6874
投稿日: 2022/03/02(Wed) 10:37
投稿者JRA-VANソフトサポート
参照先http://bit.ly/3IAxAXD
JRA-VANソフトサポートの渡部です。
DataLab.サービスをご利用いただきまして誠にありがとうございます。

JVGetsではメモリの解放を行っていないため、
アプリケーション側で解放していただく必要がございます。
「JV-Linkインターフェース仕様書 Ver.4.7.0.1」のP26に記載がございます。

C#での開発の場合、nullを代入することで
同様の事象が解消された事例が過去にございました。
当時の質問と回答へのリンクを添付いたしましたので、
よろしければご参照ください。

以上、よろしくお願いいたします。

タイトルRe^2: C#でのメモリ解放
記事No6875
投稿日: 2022/03/02(Wed) 16:20
投稿者たかひろ
参照先http://https://harigami.net/cd?hsh=352d1e9b-752d-44a1-9c57-c7e0147a69cb
JRA-VANソフトサポート 渡部様
ご返信ありがとうございます。

null代入をいくつかのパターンで試しましたがリークは解決しませんでした。
VBではなくC#ではどういった記述をすればよいか具体例をご教授いただけない
でしょうか。

下記URLはnull代入を試行したコードの抜粋です。
https://harigami.net/cd?hsh=352d1e9b-752d-44a1-9c57-c7e0147a69cb

以上、宜しくお願い致します。

タイトルRe^3: C#でのメモリ解放
記事No6877
投稿日: 2022/03/04(Fri) 01:04
投稿者サメの餌
こんばんは。

自分も以前からJVGetsには興味があり、試したいなっと思っていましたのでやってみたので参考になれば幸いです。

iReturnCode = clsJVLink.JVOpen(strDataSpec, strFromTime, Option, ref iReadCount, iDownloadCount, out strLastFileTimestamp);

int iBuffSize = 110000;
const int iNameSize = 256;
string strFileName;
object objBuff;

strFileName = new string('\0', iNameSize);
objBuff = new byte[iBuffSize];
iReturnCode = clsJVLink.JVGets(ref objBuff, iBuffSize, out strFileName);

objBuff = null;

clsJVLink.JVClose();

こんなイメージです。で、実際に得たobjBuffは使う際に、

Encoding.GetEncoding("Shift_JIS").GetString((byte[])objBuff)

って感じで文字列にするんですが、

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

をしておかないと、エラーが出た記憶があります。少しでも参考になれば幸いです。変数名が微妙なのは、元々VBで開発始めたものを途中でC#にコンバートした由来です^^; あと、strFileNameの割り当ては不要かも。

Windows11 Pro 21H2
Visual Studio Community 2022 Version 17.0.6

タイトルRe^4: C#でのメモリ解放
記事No6878
投稿日: 2022/03/04(Fri) 10:42
投稿者サメの餌
こんにちは。

昨晩サクッとやっただけだったので心配で再確認してたんですが、確かにnull
入れただけだとメモリ解放されないですね。GC.Collect()も入れてみましたが、
全く無意味でした。

お力になれませんでしたm(__)m

タイトルRe: C#でのメモリ解放
記事No6880
投稿日: 2022/03/12(Sat) 04:05
投稿者yoshy
私の検証では以下の方法によりメモリリークが解消されました。

概要としては、JVGetsの第一引数に空のbyte配列ではなく空のSafeArrayを渡すことで明示的な解放が可能となります。
(参照の戻り値がbyte配列からSafeArrayになります)

SafeArrayはC#の標準ライブラリではサポートされていませんので、OLEAUT32.DLLよりWin32 API関数を別途インポートする必要があります。

--
[DllImport("Oleaut32.dll", CallingConvention = CallingConvent
ion.StdCall)]
public static extern IntPtr SafeArrayCreateVector(VarEnum vt, int lLbound, uint cElements);

[DllImport("Oleaut32.dll", CallingConvention = CallingConvent
ion.StdCall)]
public static extern uint SafeArrayDestroy(IntPtr pSafeArray);

[DllImport("Oleaut32.dll", CallingConvention = CallingConvent
ion.StdCall)]
public static extern uint SafeArrayAccessData(IntPtr pSafeArray, ref IntPtr ppvData);

[DllImport("Oleaut32.dll", CallingConvention = CallingConvent
ion.StdCall)]
public static extern uint SafeArrayUnaccessData(IntPtr pSafeArray);

[DllImport("Oleaut32.dll", CallingConvention = CallingConvent
ion.StdCall)]
public static extern uint SafeArrayGetUBound(IntPtr pSafeArray, uint nDim, ref int lUbound);
--

データ取得の呼び出しは以下のようになります。
(字下げに全角空白を使っています)
--
IntPtr psaDummy = IntPtr.Zero;

try
{
  psaDummy = SafeArrayCreateVector(VarEnum.VT_UI1, 0, 0);
  object objBuffPtr = psaDummy;

  int readSize = jvLink.JVGets(ref objBuffPtr, 1024 * 1024, out string fileName);
  IntPtr psaBuff = IntPtr.Add(IntPtr.Zero, (int)objBuffPtr);

...
--

SafeArrayへのアクセスや解放はAPI仕様に従って適切に実装する必要があります。
(なお、空で確保したSafeArrayも解放する必要があります)

タイトルRe^2: C#でのメモリ解放
記事No6882
投稿日: 2022/03/12(Sat) 22:56
投稿者たかひろ
yoshy様

リーク無しでデータ取得可能になりました。
ご検証本当にありがとうございます!

余談ですが、第1引数はSafeArrayである必要はないようでした。
--------
static string s_filename = new string('\0', 256);
static int buffSize = 110000;

public static int JVGetsWithCSharp( out byte[] outBuff )
{
object dummyObject = (object)(IntPtr)0;
int ret = s_JVLink.JVGets(ref dummyObject, buffSize, out s_filename);

if (ret > 0)
{
IntPtr pSafeArray = (IntPtr)(int)dummyObject;

try
{
byte[] buff = outBuff = new byte[ret];
uint hr;

IntPtr ppvData = (IntPtr)0;
hr = SafeArrayAccessData(pSafeArray, ref ppvData);
if (hr != 0) throw new System.Exception(hr.ToString());

Marshal.Copy(ppvData, buff, 0, ret);

SafeArrayUnaccessData(pSafeArray);
}
finally
{
SafeArrayDestroy(pSafeArray);
}
}
else
{
outBuff = null;
}

return ret;
}
--------

タイトルRe^3: C#でのメモリ解放
記事No6883
投稿日: 2022/03/14(Mon) 00:12
投稿者yoshy
> 余談ですが、第1引数はSafeArrayである必要はないようでした。
ダミーのIntPtr.Zeroを渡すとMarshallerがSafeArrayのヌルポインタとして解釈し
てくれるんでしょうか……?
とりあえず、参考になりました。

タイトルRe^3: C#でのメモリ解放
記事No6887
投稿日: 2022/03/28(Mon) 01:01
投稿者サメの餌
yoshyさん、たかひろさん、こんばんは。

お二人のやり取り参考にJVGetsの実装が完了しました。ただ、少し残念なのはJ
VReadでのフルセットアップが14時間17分だった所、JVGetsでのフルセットアッ
プが14時間7分とセットアップのタイミングに3週間程度の差があり、若干データ
が増えてる所での10分短縮。まあ、それでも短縮出来ている事は悪い事ではない
ですが、ここまでの苦労と今後にプラスになるかは微妙な感じかも。

お二人はJVGetsでのパフォーマンスアップは期待通りでしたか?

タイトルRe^4: C#でのメモリ解放
記事No6888
投稿日: 2022/03/29(Tue) 14:06
投稿者たかひろ
こんにちわ。

私が取得しているデータの取得時間はその後処理も含めて1〜2時間程度です

生テキストで30GBぐらいの膨大なデータ量なのでまあ妥当かなと思ってます。
また、一度JVGetsで取得した後は、保存したものを使っていて再取得してない
ので特に実行時間は気にしていません。

サメの餌さんが仰っているフルセットアップ、というのは具体的にはどういう
引数でのJVOpenでしょうか?

私の場合、Tachyonさんからの情報があるまでJVGets一択だったことと、その後
も特に変更する理由がなかったのでJVGetsだけしか使っていませんが
下記条件下で1年分のRACEデータを取得してファイルに保存するプログラムの
実行時間はキャッシュ無しでも20秒程度でした。

- キャッシュ無効化のため下記ディレクトリをリネームして退避
C:\ProgramData\JRA-VAN\Data Lab\cache
C:\ProgramData\JRA-VAN\Data Lab\data

- JVOpen("RACE", "20200101000000-20201299000000", 4
) を呼び出し
キャッシュ無しで22秒
再度の実行(キャッシュあり)で11秒

フルセットアップ、とのことなのでセットアップ系の全部をいれた下記引数で
も実行
"TOKURACEDIFFBLODSNAPSLOPWOODYSCHHOSEHOYUCOMMMING"
キャッシュ無しで37秒
キャッシュありで34秒


私は2006年以降のレースに対して
RACE, SLOP, WOOD, BLOD, OB41, OB42
のデータを取得し、自分が扱いやすい形式に変換してローカルPCに保存して
います。
全部を一度に取得したことはありませんが、全部合わせても1〜2時間程度だ
ったかなと思います。

タイトルRe^5: C#でのメモリ解放
記事No6890
投稿日: 2022/03/30(Wed) 06:21
投稿者サメの餌
おはようございます。

フルセットアップはJRA-VANが提供している全てのデータの取得です。1986年位
から提供されているものや2000年以降順次なものとか、自分自身が使うかどうか
まだ決めてないものも含め全ての取得をしてあります。データベースファイルが
60ギガ程度になっててます。

時間掛かるのは出走別着度数(SNAP)が1年分で約30分前後。2004年から提供され
ているので、2004年〜2021年の18年分で単純に9時間掛かっている感じです。

データ量的に多いのはオッズデータと票数データでそれぞれ確か20ギガ超えて
る感じだったかと。ターゲットなんかだと確かオッズはソフトで計算するから票
数のみ蓄積してるんだったかと思いますが、オッズ計算が面倒で現時点では全部
取得してます。票数は使用するか未定ですが、取得はしてある。

どのデータを使うとかあまり考えずに全取得して、今後作ってく中で徐々に利
用する予定です。

タイトルRe^6: C#でのメモリ解放
記事No6891
投稿日: 2022/03/30(Wed) 20:03
投稿者たかひろ
こんばんわ。
全部ですか。それはすごい。


JVGetsのパフォーマンスをみるために
2004〜2022年のSNAPデータを取得しファイルへ保存するプログラムを作り実行
してみました。
実行時間は3分50秒で、保存されたデータのサイズは6GBでした。
また、キャッシュが効く2回目では取得時間は10秒でした。
ハードディスクにデータを保存する時間を勘案しても、JVGets自体は十分速い
のかなと思います。

SNAP1年分ですとおよそ13秒前後になります。
30分とはだいぶ違うため、おそらくサメの餌さんの環境ではJVGets以外の処
理で時間がかかっているのではないかと思います。

ソースは下記になります。ご参考になれば幸いです。
https://harigami.net/cmp_rs?hsh=1bf94cc4-5ddd-43d5-b7c4-6587b1fbbd
b7

タイトルRe: SNAPの取込が遅い
記事No6893
投稿日: 2022/04/04(Mon) 04:49
投稿者yoshy
> 時間掛かるのは出走別着度数(SNAP)が1年分で約30分前後。2004年から提供されているので、2004年〜2021年の18年分で単純に9時間掛かっている感じです。
>
> データ量的に多いのはオッズデータと票数データでそれぞれ確か20ギガ超えてる感じだったかと。

取込み先テーブルの作りとアプリ側の要件によると思いますが、子レコードの件数が爆発して遅いような場合は以下のような非正規化を検討すると良いのではないでしょうか。

・着度数は単純に表示できれば良い程度であれば、1〜n着・着外を個別のカラムにバラすのではなく非正規化した状態で取り込む(例:「3.5.5.4.12.25」のような書式)

→n着の度数を条件にしたり集約したりは出来なくなるので要件次第

・票数・オッズもとりあえず取り込むだけであれば枠番や馬番にバラさずにテーブルキー+票数/オッズ生データ+付随データくらいの粒度で取り込む

→表示するだけなら生データを都度PG側でバラした方が効率が良いと思われる。分析等したい場合は取り込んだデータをさらに別クエリや処理で専用のデータ構造にバラすとか…

○参考ログ(2022年2月分のJV-Data取込)
→前処理(データ受信)を除くとJVGets+DB保存+コミットに約6秒
→着度数データ(CK〜.jvd)の取込は2ファイル約2秒
→票数データ(H1/H6〜.jvd)の取込は3ファイル約0.5秒
→オッズデータ(O1/O2/O3/O4/O5/O6〜.jvd)の取込は7ファイル約0.5秒
--
2022-03-21 20:04:48.3935 [INFO ] [JVLinkService] 2022年02月から1ヶ月分のセットアップデータを取り込みます...
2022-03-21 20:04:48.3935 [DEBUG] [JVLinkService] info.Option = SETUP_NO_DIALOG
2022-03-21 20:04:48.3935 [DEBUG] [JVLinkService] info.DataSpec = RACEBLODSNAPSLOPWOODMING
2022-03-21 20:04:48.3935 [DEBUG] [JVLinkService] info.RecordTypeFilter = RA,SE,HR,H1,H6,O1,O2,O3,O4,O5,O6,WF,JG,HN,SK,BT,DM,TM,CK,HC,WC
2022-03-21 20:04:48.4756 [DEBUG] [JVUpdateReader] JVOpen(RACEBLODSNAPSLOPWOODMING, 20220201000000-20220301000000, 4) succeeded.
2022-03-21 20:04:48.4756 [DEBUG] [JVUpdateReader] readCount=29, downloadCount=29
2022-03-21 20:04:49.4828 [DEBUG] [JVUpdateReader] JVStatus: 6 / 29
2022-03-21 20:04:50.4853 [DEBUG] [JVUpdateReader] JVStatus: 18 / 29
2022-03-21 20:04:51.4855 [DEBUG] [JVUpdateReader] JVStatus: 29 / 29
2022-03-21 20:04:51.6930 [DEBUG] [JVUpdateReader] JVData file processed. [BTXM2022029920220228143417.jvd] ( 1 / 29) - 92 records stored.
2022-03-21 20:04:52.7039 [DEBUG] [JVUpdateReader] JVData file processed. [CKVM2022029920220228143420.jvd] ( 2 / 29) - 2,445 records stored.
2022-03-21 20:04:53.4069 [DEBUG] [JVUpdateReader] JVData file processed. [CKVM2022029920220228143425.jvd] ( 3 / 29) - 1,631 records stored.
2022-03-21 20:04:53.4656 [DEBUG] [JVUpdateReader] JVData file processed. [DMVM2022029920220228143427.jvd] ( 4 / 29) - 288 records stored.
2022-03-21 20:04:53.6164 [DEBUG] [JVUpdateReader] JVData file processed. [H1VM2022029920220228143427.jvd] ( 5 / 29) - 288 records stored.
2022-03-21 20:04:53.8723 [DEBUG] [JVUpdateReader] JVData file processed. [H6VM2022029920220228143430.jvd] ( 6 / 29) - 164 records stored.
2022-03-21 20:04:54.0688 [DEBUG] [JVUpdateReader] JVData file processed. [H6VM2022029920220228143434.jvd] ( 7 / 29) - 124 records stored.
2022-03-21 20:04:54.8283 [DEBUG] [JVUpdateReader] JVData file processed. [HCVM2022029920220228143436.jvd] ( 8 / 29) - 36,167 records stored.
2022-03-21 20:04:54.8283 [DEBUG] [JVUpdateReader] JVData file processed. [HNVM2022029920220228143437.jvd] ( 9 / 29) - 100 records stored.
2022-03-21 20:04:54.8480 [DEBUG] [JVUpdateReader] JVData file processed. [HRVM2022029920220228143437.jvd] ( 10 / 29) - 288 records stored.
2022-03-21 20:04:54.9843 [DEBUG] [JVUpdateReader] JVData file processed. [JGVM2022029920220228143545.jvd] ( 11 / 29) - 4,566 records stored.
2022-03-21 20:04:55.0038 [DEBUG] [JVUpdateReader] JVData file processed. [O1VM2022029920220228143546.jvd] ( 12 / 29) - 288 records stored.
2022-03-21 20:04:55.0277 [DEBUG] [JVUpdateReader] JVData file processed. [O2VM2022029920220228143546.jvd] ( 13 / 29) - 288 records stored.
2022-03-21 20:04:55.0563 [DEBUG] [JVUpdateReader] JVData file processed. [O3VM2022029920220228143546.jvd] ( 14 / 29) - 288 records stored.
2022-03-21 20:04:55.0904 [DEBUG] [JVUpdateReader] JVData file processed. [O4VM2022029920220228143546.jvd] ( 15 / 29) - 288 records stored.
2022-03-21 20:04:55.1641 [DEBUG] [JVUpdateReader] JVData file processed. [O5VM2022029920220228143547.jvd] ( 16 / 29) - 288 records stored.
2022-03-21 20:04:55.4349 [DEBUG] [JVUpdateReader] JVData file processed. [O6VM2022029920220228143549.jvd] ( 17 / 29) - 202 records stored.
2022-03-21 20:04:55.5471 [DEBUG] [JVUpdateReader] JVData file processed. [O6VM2022029920220228143554.jvd] ( 18 / 29) - 86 records stored.
2022-03-21 20:04:55.6070 [DEBUG] [JVUpdateReader] JVData file processed. [RAVM2022029920220228143555.jvd] ( 19 / 29) - 457 records stored.
2022-03-21 20:04:56.0899 [DEBUG] [JVUpdateReader] JVData file processed. [SEVM2022029920220228143555.jvd] ( 20 / 29) - 5,767 records stored.
2022-03-21 20:04:56.0899 [DEBUG] [JVUpdateReader] JVData file processed. [SKVM2022029920220228143556.jvd] ( 21 / 29) - 12 records stored.
2022-03-21 20:04:56.1446 [DEBUG] [JVUpdateReader] JVData file processed. [TMVM2022029920220228143556.jvd] ( 22 / 29) - 276 records stored.
2022-03-21 20:04:56.5178 [DEBUG] [JVUpdateReader] JVData file processed. [WCVM2022029920220228143820.jvd] ( 23 / 29) - 12,333 records stored.
2022-03-21 20:04:56.5178 [DEBUG] [JVUpdateReader] JVData file processed. [WFVM2022029920220228143820.jvd] ( 24 / 29) - 4 records stored.
2022-03-21 20:04:56.5433 [DEBUG] [JVUpdateReader] JVData file processed. [HCWW2022030120220301112529.jvd] ( 25 / 29) - 939 records stored.
2022-03-21 20:04:56.5433 [DEBUG] [JVUpdateReader] JVData file processed. [WCWW2022030120220301112529.jvd] ( 26 / 29) - 353 records stored.
2022-03-21 20:04:56.5770 [DEBUG] [JVUpdateReader] JVData file processed. [HCEW2022030120220301120004.jvd] ( 27 / 29) - 913 records stored.
2022-03-21 20:04:56.5770 [DEBUG] [JVUpdateReader] JVData file processed. [WCEW2022030120220301120004.jvd] ( 28 / 29) - 124 records stored.
2022-03-21 20:04:56.6090 [DEBUG] [JVUpdateReader] JVData file processed. [HCMW2022022720220304164943.jvd] ( 29 / 29) - 976 records stored.
2022-03-21 20:04:56.6090 [DEBUG] [JVUpdateReader] JVGets done.
2022-03-21 20:04:56.6090 [DEBUG] [JVUpdateReader] JVClose succeeded.
2022-03-21 20:04:56.6090 [DEBUG] [JVLinkService] LastFileTimestamp: 20220304164943
2022-03-21 20:04:56.6090 [INFO ] [JVLinkService] DBの変更をコミットしています...
2022-03-21 20:04:57.6233 [INFO ] [JVLinkService] コミットが完了しました.

タイトルフルセットアップ時の実行時間
記事No6892
投稿日: 2022/04/04(Mon) 04:11
投稿者yoshy
実装にもよると思いますが、以下の前提で約30分でした。

・取込先DBはローカルPC上のSQLite3(charset=utf8)
・JV-Data→DBレコードの変換は自作(JRA-VAN提供のソースは使用せず)
・取込期間は1986年〜最新
・マスタ系以外(RACEBLODSNAPSLOPWOODMING)は1ヶ月ずつ取り込み
・マスタ系(TOKUDIFFYSCHHOSEHOYUCOMM)は一括取り込み
・JV-Linkのキャッシュがほぼ効いている状態

○参考ログ(...はログ省略)
--
2022-03-21 19:38:18.7042 [INFO ] [JVLinkService] 1986年01月から1ヶ月分のセットアップデータを取り込みます...
2022-03-21 19:38:18.7042 [DEBUG] [JVLinkService] info.Option = SETUP_NO_DIALOG
2022-03-21 19:38:18.7042 [DEBUG] [JVLinkService] info.DataSpec = RACEBLODSNAPSLOPWOODMING
2022-03-21 19:38:18.7042 [DEBUG] [JVLinkService] info.RecordTypeFilter = RA,SE,HR,H1,H6,O1,O2,O3,O4,O5,O6,WF,JG,HN,SK,BT,DM,TM,CK,HC,WC
2022-03-21 19:38:18.7922 [DEBUG] [JVUpdateReader] JVOpen(RACEBLODSNAPSLOPWOODMING, 19860101000000-19860201000000, 4) succeeded.
2022-03-21 19:38:18.7922 [DEBUG] [JVUpdateReader] readCount=4, downloadCount=0
2022-03-21 19:38:18.9177 [DEBUG] [JVUpdateReader] JVData file processed. [H1VM1986019920181003175046.jvd] ( 1 / 4) - 262 records stored.
2022-03-21 19:38:18.9430 [DEBUG] [JVUpdateReader] JVData file processed. [HRVM1986019920181003175047.jvd] ( 2 / 4) - 262 records stored.
2022-03-21 19:38:18.9986 [DEBUG] [JVUpdateReader] JVData file processed. [RAVM1986019920181003175048.jvd] ( 3 / 4) - 418 records stored.
2022-03-21 19:38:19.2800 [DEBUG] [JVUpdateReader] JVData file processed. [SEVM1986019920181003175049.jvd] ( 4 / 4) - 3,226 records stored.
2022-03-21 19:38:19.2800 [DEBUG] [JVUpdateReader] JVGets done.
2022-03-21 19:38:19.3712 [DEBUG] [JVUpdateReader] JVClose succeeded.
2022-03-21 19:38:19.3712 [DEBUG] [JVLinkService] LastFileTimestamp: 20181003175049
2022-03-21 19:38:19.3712 [INFO ] [JVLinkService] DBの変更をコミットしています...
2022-03-21 19:38:19.3876 [INFO ] [JVLinkService] コミットが完了しました.

...

2022-03-21 20:04:58.1337 [INFO ] [JVLinkService] 2022年03月以降のセットアップデータを取り込みます...
2022-03-21 20:04:58.1337 [DEBUG] [JVLinkService] info.Option = SETUP_NO_DIALOG
2022-03-21 20:04:58.1337 [DEBUG] [JVLinkService] info.DataSpec = RACEBLODSNAPSLOPWOODMING
2022-03-21 20:04:58.1337 [DEBUG] [JVLinkService] info.RecordTypeFilter = RA,SE,HR,H1,H6,O1,O2,O3,O4,O5,O6,WF,JG,HN,SK,BT,DM,TM,CK,HC,WC
2022-03-21 20:04:58.2378 [DEBUG] [JVUpdateReader] JVOpen(RACEBLODSNAPSLOPWOODMING, 20220301000000-, 4) succeeded.
2022-03-21 20:04:58.2378 [DEBUG] [JVUpdateReader] readCount=158, downloadCount=140
2022-03-21 20:04:59.2377 [DEBUG] [JVUpdateReader] JVStatus: 40 / 140
2022-03-21 20:05:00.2474 [DEBUG] [JVUpdateReader] JVStatus: 77 / 140
2022-03-21 20:05:01.2479 [DEBUG] [JVUpdateReader] JVStatus: 122 / 140
2022-03-21 20:05:02.2609 [DEBUG] [JVUpdateReader] JVStatus: 140 / 140
2022-03-21 20:05:02.2918 [DEBUG] [JVUpdateReader] JVData file processed. [HCWW2022030220220302112519.jvd] ( 1 / 158) - 853 records stored.
2022-03-21 20:05:02.2918 [DEBUG] [JVUpdateReader] JVData file processed. [WCWW2022030220220302112519.jvd] ( 2 / 158) - 404 records stored.

...

2022-03-21 20:05:07.3261 [DEBUG] [JVUpdateReader] JVData file processed. [HCEW2022032120220321123004.jvd] (157 / 158) - 744 records stored.
2022-03-21 20:05:07.3261 [DEBUG] [JVUpdateReader] JVData file processed. [WCEW2022032120220321123004.jvd] (158 / 158) - 246 records stored.
2022-03-21 20:05:07.3261 [DEBUG] [JVUpdateReader] JVGets done.
2022-03-21 20:05:07.3508 [DEBUG] [JVUpdateReader] JVClose succeeded.
2022-03-21 20:05:07.3508 [DEBUG] [JVLinkService] LastFileTimestamp: 20220321123004
2022-03-21 20:05:07.3508 [INFO ] [JVLinkService] DBの変更をコミットしています...
2022-03-21 20:05:08.1683 [INFO ] [JVLinkService] コミットが完了しました.
2022-03-21 20:05:08.2034 [INFO ] [JVLinkService] 0000年00月以降のセットアップデータを取り込みます...
2022-03-21 20:05:08.2034 [DEBUG] [JVLinkService] info.Option = SETUP_NO_DIALOG
2022-03-21 20:05:08.2034 [DEBUG] [JVLinkService] info.DataSpec = TOKUDIFFYSCHHOSEHOYUCOMM
2022-03-21 20:05:08.2034 [DEBUG] [JVLinkService] info.RecordTypeFilter = UM,KS,CH,BR,BN,RC,RA,SE,YS,HS,HY,CS,TK
2022-03-21 20:05:08.3467 [DEBUG] [JVUpdateReader] JVOpen(TOKUDIFFYSCHHOSEHOYUCOMM, 00000000000000-, 4) succeeded.
2022-03-21 20:05:08.3467 [DEBUG] [JVUpdateReader] readCount=90, downloadCount=66
2022-03-21 20:05:09.3577 [DEBUG] [JVUpdateReader] JVStatus: 11 / 66
2022-03-21 20:05:10.3706 [DEBUG] [JVUpdateReader] JVStatus: 15 / 66
2022-03-21 20:05:11.3846 [DEBUG] [JVUpdateReader] JVStatus: 19 / 66
2022-03-21 20:05:12.3916 [DEBUG] [JVUpdateReader] JVStatus: 23 / 66
2022-03-21 20:05:13.4027 [DEBUG] [JVUpdateReader] JVStatus: 27 / 66
2022-03-21 20:05:14.4078 [DEBUG] [JVUpdateReader] JVStatus: 56 / 66
2022-03-21 20:05:15.4164 [DEBUG] [JVUpdateReader] JVStatus: 66 / 66
2022-03-21 20:05:16.1820 [DEBUG] [JVUpdateReader] JVData file processed. [YSYM2000999920181003180603.jvd] ( 1 / 90) - 291 records stored.
2022-03-21 20:05:16.1820 [DEBUG] [JVUpdateReader] JVData file processed. [YSYM2001999920181003180732.jvd] ( 2 / 90) - 291 records stored.

...

2022-03-21 20:06:36.8401 [DEBUG] [JVUpdateReader] JVData file processed. [UMOW2022031820220318131329.jvd] ( 89 / 90) - 1 records stored.
2022-03-21 20:06:36.9103 [DEBUG] [JVUpdateReader] JVData file processed. [TKTW2022032120220321171949.jvd] ( 90 / 90) - 21 records stored.
2022-03-21 20:06:36.9103 [DEBUG] [JVUpdateReader] JVGets done.
2022-03-21 20:06:36.9229 [DEBUG] [JVUpdateReader] JVClose succeeded.
2022-03-21 20:06:36.9229 [DEBUG] [JVLinkService] LastFileTimestamp: 20220321171949
2022-03-21 20:06:36.9229 [INFO ] [JVLinkService] DBの変更をコミットしています...
2022-03-21 20:06:40.3782 [INFO ] [JVLinkService] コミットが完了しました.
2022-03-21 20:06:40.3972 [INFO ] [JVLinkService] JV-Data用データベースを最適化しています...
2022-03-21 20:06:40.3972 [INFO ] [JVLinkService] 完了しました.
--

○取込結果(ファイルサイズ)
--
2022/03/23 12:15 16,808,640,512 jvdata.db
2022/03/23 23:48 12,288 metadata.db
2 個のファイル 16,808,652,800 バイト
--

タイトルRe: フルセットアップ時の実行時間
記事No6894
投稿日: 2022/04/04(Mon) 17:36
投稿者サメの餌
こんばんは、たかひろさん、yoshyさん。

14時間は滅茶苦茶遅いですねorz こちらもSQLite3に登録してます。JVData_Str
uct.csを手抜きで利用させて頂いてます。DB設計はあまり深く考えずに出走別着
度数では1,700項目超/recだったりするので激遅なんだと思います。

機会があれば改善してみようと思います。お二人の書き込みは大変参考になり
ます。ありがとうございます。

何度も返信の書き込みにトライしてますが、制限エラーで出来ない日々が続い
てます。なので、これは試しにGoogle Chromeにしてみました。普段はEdgeです

タイトルRe: 取込処理の高速化
記事No6895
投稿日: 2022/04/04(Mon) 20:01
投稿者yoshy
実装はSQLite3とのことですが、現状がベタ実装であれば以下のようなチューニ
ングや改修をしてみると良いかも知れません。

・接続文字列でジャーナルモードやロックモードを性能を重視した設定に変更
する

→"Data Source=〜;synchronous=off;journal mode=wal;locking_mode=ex
clusive;temp_store=memory;mmap_size=30000000000;"等

・プリペアドステートメントを使う

・同一キーか毎回SELECTせずに、INSERT INTO 〜 ON CONFLICT 〜 文を使って
重複行をマージする

またJV-Linkの仕様上、以下のような実装になっていると遅くなります

・JVデータの取込処理を別スレッドで動かす

→JV-LinkがSTAモデルで実装されているため、COMが実行されているメインスレ
ッド上で取込処理を動かさないとスレッド間での余分なデータ交換が発生し死ぬ
ほど遅くなります(ActiveXの仕様)

→別スレッドに分けたい場合は、そのスレッドをSTAで起動してJV-Linkコント
ロールを含むウィンドウを表示し、メインアプリとは別の独自のメッセージルー
プを回します(Application.Run()する)

・JVOpenに指定している取込期間が長い(全期間一括等)

→「00000000000000-」など長期間を指定するとデータ取込が進むにつれてJV-L
inkの応答性能が次第に低下していき、最終的に耐えがたいほど遅くなります(J
V-Linkの作りの問題?)

→1ヶ月ごとなどに区切って取り込むと性能低下を回避できます

タイトルRe^2: 取込処理の高速化
記事No6911
投稿日: 2022/04/20(Wed) 18:40
投稿者サメの餌
yoshyさん、こんばんは。

SQLiteの接続文字列で

SQLiteConnectionStringBuilder sqlBuilder = new SQLiteConnectionStringBu
ilder()
{
DataSource = Properties.Settings.Default.KSD_Data_Source,
Version = 3,
LegacyFormat = false,
SyncMode = SynchronizationModes.Off,
JournalMode = SQLiteJournalModeEnum.Wal
};

としてみましたが、特に変わりませんでした。他のコーディングでは14時間が1
3時間程度には短縮出来ました。ちと、諸々対処して努力してます。

タイトルRe^3: 取込処理の高速化
記事No6913
投稿日: 2022/04/23(Sat) 16:36
投稿者サメの餌
yoshyさん、こんにちは。

話が本来のスレと違ってきたので別の新規で書込みを試みましたが、また蹴ら
れたのでこちらに書いてみます。System.Data.SQLite.Coreを使ってるのですが
、接続文字列の指定の影響は微妙で、教えて頂いたのがベストな感じですが、接
続文字列としてではなくPRAGMAとしてコネクションをオープンして実行する形で
するのが良い感じなので、現在再度フルセットアップ実行中です。System.Data.
SQLite.Coreを利用してますが、yoshyさんの30分には程遠いですが、現状出来る
限りしての結果を明日朝には報告出来るかも^^;

タイトルRe^4: 取込処理の高速化
記事No6915
投稿日: 2022/04/24(Sun) 08:06
投稿者サメの餌
yoshyさん、おはようございます。

結果からですが、相変わらず14時間越えorz まあ、1か月単位の指定になったの
で、3月分までフルセットアップで取り込んでるので1か月分増えてはいますが。

あっ、で、問題が一つ判明しました。うちのPCは16ギガ積んでますが、やはり(
?)開発環境としてはメモリ足りない模様。SQLite errorが出てまして、「メモリ
リソースが足りません」と出てました。これがネックになっているかもです。8+
8を16+16に変更したいと前々から思ってたんですが、コロナの影響からの半導体
不足で買い時ではないと我慢してたんですが、問題に直面すると何とか予算工面
して増設してみたいです。

タイトルRe^5: 取込処理の高速化
記事No6916
投稿日: 2022/04/24(Sun) 17:51
投稿者サメの餌
yoshyさん、こんにちは。

今朝、結局32GBx2枚を発注しました。互換性なんかの問題なければ明日午前中
に届く予定なので、入れてどうなのか試してみます。また、報告します。

タイトルRe^6: 取込処理の高速化
記事No6918
投稿日: 2022/04/25(Mon) 12:57
投稿者サメの餌
yoshyさん、こんにちは。

本日メモリ届いてPCに組込後、OSで64GB認識してるのを確認して実行してみる
とメモリ不足のエラーは出なくなってましたが、実行速度は変わりませんでした
。まだ何か原因があるんだと思います。

出走別着度数のテーブル設計上の問題は別として、坂路調教なんかの4万レコ
ード/ファイルな読込も30秒強掛かる感じでテーブル設計とは別にSQLiteの処理
が遅い気がします。

もう少し色々と接続文字列変更したりで改善するか模索してみます。

タイトルRe^7: 取込処理の高速化
記事No6923
投稿日: 2022/05/03(Tue) 11:04
投稿者yoshy
SQLiteのメモリ消費ですが、フルセットアップを完走した状態でも数MBだった気
がします。(データベースの保持先はディスクです)

消費量は以下のような感じでコネクションから取れます。
HighWaterは実行中の最大値となるので、全ての処理が完了した後に取得すると
良いでしょう。

> String.Format("SQLite MemoryUsed: {0:#,0} / {1:#,0} MB",
> ((conn as SQLiteConnection).MemoryUsed / (1024 * 1024)),
> ((conn as SQLiteConnection).MemoryHighwater) / (1024 * 1024));

ちなみに、Visual Studio のデバッグセッションで表示されているプログラム(
C# WPF製)全体のメモリ消費量は200〜300MB程度でした。

また、Visual Studio 自体のメモリ消費量は500MB程度のようです。

> SQLiteの処理が遅い気がします

以下でまだ遅いようなら、DB更新以外にボトルネックがあるかも知れません。

・DB更新ではなくファイルへの単純な書き込みにしてみる
・または単純にDB更新処理をコメントアウトしてみる(JV-Linkからの読み込み
のみにする)

タイトルRe^7: 取込処理の高速化
記事No6925
投稿日: 2022/05/03(Tue) 19:28
投稿者たかひろ
こんばんわ

もしボトルネックがSQLiteで確定していないならVisualStudioのプロファイラ
を使ってみてはどうでしょうか。

https://docs.microsoft.com/ja-jp/visualstudio/profiling/profiling-
feature-tour?view=vs-2022

自前のコードなら行単位で実行時間の把握ができます。
ソースがない外部DLLでもどの関数呼び出しが重いかは判明するかと思います。
また長時間(数時間以上?)実行すると恐らく最後の解析でハングするので1
5分か30分程度で実行を打ち切ると良いです。

タイトルRe: 掲示板の書き込みエラー
記事No6896
投稿日: 2022/04/04(Mon) 20:51
投稿者yoshy
> 何度も返信の書き込みにトライしてますが、制限エラーで出来ない日々が続いてます。

こちらも投稿時になぜか毎回エラーになりますが、裏では書き込みに成功しているようなのでリスト一覧に戻ると問題なく記事が追加されています。(掲示板の動作不良?)

【追記】今回は問題なく書き込めました。文章の長さによってエラーが出たり出なかったりするのでしょうか。いずれにせよ、書き込み前には内容をエディッタ等にバックアップしておいた方が良いですね……。

タイトルRe^2: 掲示板の書き込みエラー
記事No6904
投稿日: 2022/04/19(Tue) 10:04
投稿者BON
横入りすいません。
1ヶ月単位にすると高速化するんですね。今まで気にしてなかったのでありがた
い情報です。
蓄積系の初期構築に時間がかかるのは悩ましいですがそれだけのデータ量があ
りますからね。

JVReadよりJVGetの方が高速なのは間違いないです。
ただそれにしても14時間はかかりすぎな気がしますね。
ご存知かもしれませんがyoshyさんご指摘の内容に加えてSqliteの場合トランザ
クションをかけないと書き込みが異常に遅くなるのでトランザクションは必須か
と。
あとメモリに余裕があるならインメモリのテーブルに全部書き込んでから一括
でファイルDBに書き込むのも有りかと。
中断・再開などを考えるとコードが面倒になりますけど。
他のDBならストアドを使うところですがSqliteにはないですからね。
未だ試行錯誤中です。

タイトルRe^3: 掲示板の書き込みエラー
記事No6912
投稿日: 2022/04/20(Wed) 18:45
投稿者サメの餌
BONさん、こんばんは。

アドバイスありがとうございます。トランザクションは入れてます。当初、楽
々EntityFrameworkしてましたが、劇遅なので色々調べてちょっとマシになって
ます^^; でも、皆さんに遅いと言われて努力してます。

タイトルRe^4: 掲示板の書き込みエラー
記事No6914
投稿日: 2022/04/23(Sat) 16:45
投稿者サメの餌
BONさん、こんにちは。

僕はSystem.Data.SQLite.Core利用してますが、BONさんは何使ってます?

タイトルRe^5: 掲示板の書き込みエラー
記事No6917
投稿日: 2022/04/25(Mon) 09:13
投稿者BON
サメの餌 様
私も同じです。
ちなみに私の場合はC#ではなくVB.NETなので本題のメモリリークの件について
は今後C#でやる場合の参考にさせて頂きますね。

あとVisualStudioは2019から2022に移行するにあたっても色々参考にさせても
らいました。
JV-Linkのx64ネイティブ対応を急いでほしいところですね。

タイトルRe^2: 掲示板の書き込みエラー
記事No6905
投稿日: 2022/04/19(Tue) 10:05
投稿者BON
横入りすいません。
1ヶ月単位にすると高速化するんですね。今まで気にしてなかったのでありがた
い情報です。
蓄積系の初期構築に時間がかかるのは悩ましいですがそれだけのデータ量があ
りますからね。

ただそれにしても14時間はかかりすぎな気がしますね。
ご存知かもしれませんがyoshyさんご指摘の内容に加えてSqliteの場合トランザ
クションをかけないと書き込みが異常に遅くなるのでトランザクションは必須か
と。
あとメモリに余裕があるならインメモリのテーブルに全部書き込んでから一括
でファイルDBに書き込むのも有りかと。
中断・再開などを考えるとコードが面倒になりますけど。
他のDBならストアドを使うところですがSqliteにはないですからね。
未だ試行錯誤中です。

タイトルRe^2: 掲示板の書き込みエラー
記事No6924
投稿日: 2022/05/03(Tue) 11:06
投稿者yoshy
今日も、No.6923の書き込み時にエラーが出ましたが、
そのまま放置して掲示板一覧に戻ると正常に書き込めていました。

タイトルRe^3: 掲示板の書き込みエラー
記事No6926
投稿日: 2022/05/04(Wed) 18:39
投稿者サメの餌
こちらでは、ここ最近は書込み時のエラーが無くなってます。OSのクリーンイン
ストールが良かったのか、何が良かったのか不明ですが、普通に書き込めるのは
助かります。

タイトルRe: フルセットアップ時の実行時間
記事No6931
投稿日: 2022/05/08(Sun) 18:22
投稿者サメの餌
yoshyさん、たかひろさん、こんばんは。

お二人の投稿参考に14時間掛かっていたフルセットアップが今では2時間で済む
まで改善する事が出来ました。本当にありがとうございます。これ以上は自分の
スキル的にもハードルが高過ぎて、そもそものデータベース構築以降の開発が進
まないので、妥協してみます。一連の開発後にJV-Linkの64bit化なんかもあるか
な〜っと期待しながら進められればと思います。

また、困った時にはアドバイス頂ければ幸いです。

タイトルRe^2: フルセットアップ時の実行時間
記事No6935
投稿日: 2022/05/10(Tue) 01:31
投稿者yoshy
お役に立てて何よりでした。
改善お疲れさまでした。

ウィンドウを閉じる