Вопрос по string – Как получить время в миллисекундах

6

Поскольку производительность конкатенации строк в VB6 довольно низкая, я тестирую несколько реализаций StringBuilder. Чтобы увидеть, как долго они работают, я в настоящее время использую встроенный

Timer

функция, которая дает мне только количество секунд, прошедших после полуночи.

Есть ли способ (я думаю, импортируя системную функцию), чтобы получить что-то с точностью до миллисекунд?

Ваш Ответ

8   ответов
-2

Вы можете попробовать использовать Систему :: Диагностика :: Секундомер

Imports System.Diagnostics

Dim sw As New Stopwatch()
sw.Start()
// do something
LOG("Elapsed " + sw.ElapsedMilliseconds + " ms")
.NET StopWatch использует QueryPerformanceCounter / QueryPerformanceFrequency в фоновом режиме, где это возможно (вы можете узнать, используется ли он, изучив свойство IsHighResolution в StopWatch)
Извините, это моя ошибка. Тогда GetTickCount - это путь в VB6, поскольку он является альтернативой объекту clock_t в C / C ++.
Это код .NET, он специально сказал VB6 (который был последним выпуском перед выпуском .NET 1.0)
1
7

Поместите следующий код в класс секундомера:

Option Explicit

Private Declare Function QueryPerformanceCounter Lib "Kernel32" (X As Currency) As Boolean
Private Declare Function QueryPerformanceFrequency Lib "Kernel32" (X As Currency) As Boolean

Private m_startTime As Currency
Private m_freq As Currency
Private m_overhead As Currency

Public Sub start()
    QueryPerformanceCounter m_startTime
End Sub

Public Function ElapsedSeconds() As Double
    Dim currentTime As Currency
    QueryPerformanceCounter currentTime
    ElapsedSeconds = (currentTime - m_startTime - m_overhead) / m_freq
End Function

Public Function ElapsedMilliseconds() As Double
    ElapsedMilliseconds = ElapsedSeconds * 1000
End Function

Private Sub Class_Initialize()
    QueryPerformanceFrequency m_freq
    Dim ctr1 As Currency
    Dim ctr2 As Currency
    QueryPerformanceCounter ctr1
    QueryPerformanceCounter ctr2
    m_overhead = ctr2 - ctr1
End Sub

Вы можете использовать его следующим образом:

Dim sw as StopWatch
sw = New StopWatch
sw.Start

' Code you want to time

Debug.Print "Code took " & sw.ElapsedMilliseconds " ms"
Это также очень удобно для сбора некоторой статистики отладки или реализации регистратора производительности. RobertB
0

Я всегда использую это в модуле где-то (хотя может быть в классе). Этот код позволяет поддерживать до шести таймеров с высокой точностью:

Option Explicit

Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long

Private cFrequency As Currency
Private cCounters(0 To 5) As Currency

Public Sub StartCounter(Optional lCounterIndex As Long)
    QueryPerformanceFrequency cFrequency
    QueryPerformanceCounter cCounters(lCounterIndex)
End Sub

Public Function GetCounter(Optional lCounterIndex As Long) As Double
    Dim cCount As Currency

    QueryPerformanceFrequency cFrequency
    QueryPerformanceCounter cCount
    GetCounter = Format$((cCount - cCounters(lCounterIndex) - CCur(0.0008)) / cFrequency, "0.000000000")
End Function

Public Function Scientific(ByVal dValue As Double) As String
    Dim lMultiplier As Long
    Dim vNames As Variant

    lMultiplier = 5
    vNames = Array("peta", "tera", "giga", "mega", "kilo", "", "milli", "micro", "nano", "pico", "femto")
    If Abs(dValue) < 1 Then
        While Abs(dValue) < 1
            dValue = dValue * 1000
            lMultiplier = lMultiplier + 1
        Wend
    ElseIf Abs(dValue) >= 1000 Then
        While Abs(dValue) >= 1000
            dValue = dValue / 1000
            lMultiplier = lMultiplier - 1
        Wend
    End If

    Scientific = Format$(dValue, "0.000") & " " & vNames(lMultiplier)
End Function
1

Есть история Томаса Эдисона, где он берет интервью у некоторых предполагаемых инженеров.

Он просит их определить объем лампочки. Кандидат А измеряет его, а затем использует формулу для объема сферы, а другую формулу для объема шеи и так далее. Кандидат В наполняет его водой и наливает в мерный стаканчик. Как вы думаете, кто получил работу?

Запустите его 1000 раз и посмотрите на часы до и после. Секунды = миллисекунды.

12

Да, вы можете использовать Win32 API:

DWORD WINAPI GetTickCount(void);

Чтобы импортировать его в VB6, объявите его так:

Private Declare Function GetTickCount Lib "kernel32" () As Long

Позвоните до операции и после, а затем рассчитайте разницу во времени.

Да, статья Раймондаblogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx хорошо, он все еще ссылается на разрешение системного таймера, однако он советует также использовать QueryPerformanceCounter, который также требует некоторого времени для выполнения - так что есть компромиссы. Однако полезно знать.
GetTickCount достаточно хорош для большинства целей, если вы знаете, если его ограничения, попробуйте код вsupport.microsoft.com/kb/172338 однако, чтобы убедиться, что точность 10 мс - это лучшее, что вы можете получить в любой системе Windows
Точность GetTickCount составляет всего 10 мс. Если вам нужна более высокая точность, используйте QueryPerformanceCounter.
msdn ничего не говорит о 10 мс, но говорит: «Разрешение ограничено разрешением системного таймера. На это значение также влияют корректировки, сделанные функцией GetSystemTimeAdjustment. & Quot; так может 10мс для твоей конкретной машины?
1

Вы можете использовать два Win32 API:

Они используют LARGE_INTEGER для представления 64-битных чисел.

Error: User Rate Limit Exceededsupport.microsoft.com/kb/172338
2

Вы также можете рассмотреть возможность использования другого подхода. Попробуйте вызвать ваши подпрограммы из цикла с достаточным количеством итераций, чтобы получить измеримую разницу во времени.

Похожие вопросы