/// <summary>測定終了メソッド</summary> /// <returns>処理が成功した場合:結果文字列、失敗した場合:エラーメッセージ</returns> /// <remarks>自由に利用できる。</remarks> public string EndsPerformanceRecord() { #if NETSTD this._stopwatch.Stop(); this._ExecTime = this._stopwatch.ElapsedMilliseconds.ToString(); return ("ExT:" + this._ExecTime + "[msec]" + ", CT: - [msec]" + ", KT: - [msec]" + ", UT: - [msec]"); #else try { #region 実行時間取得処理セクション // システム時刻(End) UInt64 u64ExTE = 0; long lngExTE = 0; if (QPCounterWin32.QueryPerformanceCounter(ref lngExTE) != 0) // 時間の計測を開始します。 { // 周波数(更新頻度)を取得 long lngFreq = 0; QPCounterWin32.QueryPerformanceFrequency(ref lngFreq); // 秒単位 double dblTemp = ((lngExTE - LngExTS) * 1.0 / lngFreq); // 1s → 100(ns)に合わせる。 dblTemp = dblTemp * 1000 * 1000 * 10; // 整数値に変更 u64ExTE = (UInt64)Math.Round(dblTemp); } else// 高分解能のカウンタはサポートされません。 { // 100ns間隔(精度は低い) u64ExTE = Convert.ToUInt64(DateTime.Now.Ticks); } #endregion #region CPU時間取得処理セクション // カレントスレッドのハンドルを返す(IDではないので注意)。 IntPtr iptHdr; iptHdr = CmnWin32.GetCurrentThread(); // スレッドの作成時刻 System.Runtime.InteropServices.ComTypes.FILETIME ftCreateTime; // スレッドの終了時刻 System.Runtime.InteropServices.ComTypes.FILETIME ftDELETETime; // カーネル時間 System.Runtime.InteropServices.ComTypes.FILETIME ftKernelTime; // ユーザ時間 System.Runtime.InteropServices.ComTypes.FILETIME ftUserTime; // 初期化が必要? ftCreateTime.dwHighDateTime = 0; ftCreateTime.dwLowDateTime = 0; ftDELETETime.dwHighDateTime = 0; ftDELETETime.dwLowDateTime = 0; ftKernelTime.dwHighDateTime = 0; ftKernelTime.dwLowDateTime = 0; ftUserTime.dwHighDateTime = 0; ftUserTime.dwLowDateTime = 0; // Win32 API関数(GetCurrentThread) QPCounterWin32.GetThreadTimes(iptHdr, ref ftCreateTime, ref ftDELETETime, ref ftKernelTime, ref ftUserTime); // 計算用の領域 UInt32 u32KTH; UInt32 u32KTL; UInt32 u32UTH; UInt32 u32UTL; // 変換(int32 ⇒ uint32) u32KTH = Convert.ToUInt32(ftKernelTime.dwHighDateTime); u32KTL = Convert.ToUInt32(ftKernelTime.dwLowDateTime); u32UTH = Convert.ToUInt32(ftUserTime.dwHighDateTime); u32UTL = Convert.ToUInt32(ftUserTime.dwLowDateTime); // CPU時間:(uint64 * uint32) + uint64 ⇒ uint64(オーバーフローはしない) // カーネル時間(End) UInt64 u64KTE; u64KTE = Convert.ToUInt64((u32KTH * U64HIBIT) + u32KTL); // ユーザ時間(End) UInt64 u64UTE; u64UTE = Convert.ToUInt64((u32UTH * U64HIBIT) + u32UTL); #endregion #region 出力文字列作成セクション // 当該処理の実行時間を算出 UInt64 u64ExT; u64ExT = u64ExTE - U64ExTS; // 当該処理のCPU(カーネル)時間を算出 UInt64 u64KT; u64KT = u64KTE - U64KTS; // 当該処理のCPU(ユーザ)時間を算出 UInt64 u64UT; u64UT = u64UTE - U64UTS; // 当該処理のCPU時間を算出 // ※ オーバーフローは無いはず... UInt64 u64CT; u64CT = u64KT + u64UT; // 初期化 U64ExTS = 0; U64KTS = 0; U64UTS = 0; // 測定結果を文字列で返す double temp; // 四捨五入(msecの整数) temp = Math.Floor((u64ExT * 0.1 * 0.001) + 0.5); this._ExecTime = temp.ToString(); temp = Math.Floor((u64CT * 0.1 * 0.001) + 0.5); this._CpuTime = temp.ToString(); temp = Math.Floor((u64KT * 0.1 * 0.001) + 0.5); this._CpuKernelTime = temp.ToString(); temp = Math.Floor((u64UT * 0.1 * 0.001) + 0.5); this._CpuUserTime = temp.ToString(); return ("ExT:" + this._ExecTime + "[msec]" + ", CT:" + this._CpuTime + "[msec]" + ", KT:" + this._CpuKernelTime + "[msec]" + ", UT:" + this._CpuUserTime + "[msec]"); #endregion } catch (Exception ex) { // ランタイムエラー。 return(ex.Message); } #endif }
/// <summary>測定開始メソッド</summary> /// <returns>処理が成功した場合:True、失敗した場合:False</returns> /// <remarks>自由に利用できる。</remarks> public bool StartsPerformanceRecord() { #if NETSTD this._stopwatch = new Stopwatch(); this._stopwatch.Start(); #else #region メンバ変数を初期化する // 実行時間 this.U64ExTS = 0; this.LngExTS = 0; // QueryPerformanceCounter用 // CPU時間 this.U64KTS = 0; this.U64UTS = 0; // 測定結果の保存用メンバ変数の初期化 this._ExecTime = ""; this._CpuTime = ""; this._CpuKernelTime = ""; this._CpuUserTime = ""; #endregion try { #region 実行時間取得処理セクション // システム時刻(Start) if (QPCounterWin32.QueryPerformanceCounter(ref LngExTS) != 0) // 時間の計測を開始します。 { } else// 高分解能のカウンタはサポートされません。 { // 100ns間隔(精度は低い) U64ExTS = Convert.ToUInt64(DateTime.Now.Ticks); } #endregion #region CPU時間取得処理セクション // カレントスレッドのハンドルを返す(IDではないので注意)。 IntPtr iptHdr; iptHdr = CmnWin32.GetCurrentThread(); // スレッドの作成時刻 System.Runtime.InteropServices.ComTypes.FILETIME ftCreateTime; // スレッドの終了時刻 System.Runtime.InteropServices.ComTypes.FILETIME ftDELETETime; // カーネル時間 System.Runtime.InteropServices.ComTypes.FILETIME ftKernelTime; // ユーザ時間 System.Runtime.InteropServices.ComTypes.FILETIME ftUserTime; // 初期化が必要? ftCreateTime.dwHighDateTime = 0; ftCreateTime.dwLowDateTime = 0; ftDELETETime.dwHighDateTime = 0; ftDELETETime.dwLowDateTime = 0; ftKernelTime.dwHighDateTime = 0; ftKernelTime.dwLowDateTime = 0; ftUserTime.dwHighDateTime = 0; ftUserTime.dwLowDateTime = 0; // Win32 API関数(GetCurrentThread) QPCounterWin32.GetThreadTimes(iptHdr, ref ftCreateTime, ref ftDELETETime, ref ftKernelTime, ref ftUserTime); // 計算用の領域 UInt32 u32KTH; UInt32 u32KTL; UInt32 u32UTH; UInt32 u32UTL; // 変換(int32 ⇒ uint32) u32KTH = Convert.ToUInt32(ftKernelTime.dwHighDateTime); u32KTL = Convert.ToUInt32(ftKernelTime.dwLowDateTime); u32UTH = Convert.ToUInt32(ftUserTime.dwHighDateTime); u32UTL = Convert.ToUInt32(ftUserTime.dwLowDateTime); // CPU時間:(uint64 * uint32) + uint64 ⇒ uint64(オーバーフローはしない) // カーネル時間(Start) U64KTS = Convert.ToUInt64((u32KTH * U64HIBIT) + u32KTL); // ユーザ時間(Start) U64UTS = Convert.ToUInt64((u32UTH * U64HIBIT) + u32UTL); #endregion } catch { // ランタイムエラー。 return(false); } finally { } #endif return(true); }