Циклическая оптимизация в QB64 - PullRequest
0 голосов
/ 18 сентября 2018

Иметь цикл в QB64 относительно оптимизации цикла:

DIM N AS DOUBLE, X(100000000) AS DOUBLE
T! = TIMER
FOR N = 1 to 100000000
    IF X(N) THEN
        PRINT X(N)
        EXIT FOR
    END IF
NEXT
PRINT TIMER - T!

это быстрее чем:

DIM N AS DOUBLE, X(100000000) AS DOUBLE
T! = TIMER
FOR N = 1 to 100000000
    IF X(N) <> 0  THEN
        PRINT X(N)
        EXIT FOR
    END IF
NEXT
PRINT TIMER - T!

РЕДАКТИРОВАНИЕ: 09-18-2018 для включения типов переменных

1 Ответ

0 голосов
/ 03 января 2019

Я написал этот код для оценки вашего теста:

REM Delete REM to enable console runs
REM $CONSOLE:ONLY
REM _DEST _CONSOLE

DIM SHARED N AS DOUBLE, X(100000000) AS DOUBLE

S# = 0: ZC% = 0
T% = 10
IF COMMAND$ <> "" THEN
    T% = VAL(COMMAND$)
END IF

IF T% > 999 THEN T% = 999

FOR I% = 1 TO T%
    A# = TRYA
    B# = TRYB

    D# = A# - B#
    PRINT USING "Case A ... : #.########"; A#
    PRINT USING "Case B ... : #.########"; B#
    PRINT USING "Diff ..... : #.########"; D#;

    A$ = ""
    IF ABS(D#) < 0.00000001 THEN
        ZC% = ZC% + 1
        A$ = "*"
    END IF

    S# = S# + A# - B#

    PRINT A$
    PRINT

    REM INKEY$ doesn't work in console mode!
    A$ = INKEY$
    IF A$ = CHR$(27) THEN
        I% = I% + 1: EXIT FOR
    END IF
NEXT

PRINT USING "Avrg A - B : #.########"; S# / (I% - 1)
PRINT USING "0 diff:### on ### tryes"; ZC%, (I% - 1)
PRINT

PRINT "Hit a key to exit!"
REM INPUT$ doesn't work in console mode!
A$ = INPUT$(1)
SYSTEM


FUNCTION TRYA#
    T# = TIMER
    FOR N = 1 TO 100000000
        IF X(N) THEN
            PRINT X(N)
            EXIT FOR
        END IF
    NEXT
    A# = TIMER - T#

    TRYA = A#
END FUNCTION

FUNCTION TRYB#
    T# = TIMER
    FOR N = 1 TO 100000000
        IF X(N) <> 0 THEN
            PRINT X(N)
            EXIT FOR
        END IF
    NEXT
    A# = TIMER - T#

    TRYB = A#
END FUNCTION

Две разные подпрограммы вставляются в две функции: TRYA и TRYB.

Я запустил этот SW с циклом, который выполняет функции в 999 раз, и в результате получается:

Avrg. A - B: 0.00204501
0 diff:359 on 999 tryes

Затем я запустил цикл 10 раз, и результат:

Avrg. A - B: -.01640625
0 diff:  1 on  10 tryes

Затем я запустил цикл 15 раз, и результат:

Avrg. A - B: 0.00026042
0 diff:  5 on  15 tryes

Потому что мы запускаем SW в многопоточном окружении. Не думаю, что это очень хороший тест, но есть некоторые результаты:

  1. В двух случаях результаты без разницы (0 различий) составляют треть всех циклов.
  2. В двух случаях кажется, что функция TRYA медленнее.
  3. В одном случае кажется, что функция TRYB медленнее.

Глядя на эти результаты, я думаю, мы можем считать две функции эквивалентными!

Вы получаете более 10 циклов, выполняющих код из командной строки (или изменяя параметр $ command в меню QB64) как:

# ./test n

Где n - количество желаемых петель.

SW был скомпилирован с использованием gcc с опцией оптимизации -O3. (Для этого вам нужно изменить файл [/opt/]qb64/internal/c/makeline_lnx.txt)

...