Пример #1
0
        /// <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
        }
Пример #2
0
        /// <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);
        }