QB64 中的循环优化

Posted

技术标签:

【中文标题】QB64 中的循环优化【英文标题】:Loop optimization in QB64 【发布时间】:2018-09-18 05:00:32 【问题描述】:

在 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 包括变量类型

【问题讨论】:

信息不足。 “N”是什么类型?函数“X”返回什么类型?您不能简单地使用计时器并自己测试吗? 我对这两个例程进行了计时器测试,它们返回相同的精确时间到毫秒。 在退出循环之前执行了多少次迭代? 这可能是您的答案:“我对这两个例程进行了计时器测试,它们返回相同的精确时间到毫秒。” - 你 @Bill:由于数组是用 100000000 个元素定义为零的,所有这些元素。 【参考方案1】:

我写了这段代码来评估你的测试:

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

两个不同的例程被插入到两个函数中:TRYATRYB

我用一个循环运行 999 次函数的循环启动了这个 SW,结果是:

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 我不认为这是一个很好的测试,但有一些结果:

    在两种情况下,无差异 (0 diff) 的结果占所有循环的三分之一。 在两种情况下,TRYA 函数似乎更慢。 在一种情况下,TRYB 函数似乎更慢。

看这些结果,我想,我们可以认为这两个函数是等价的!​​p>

您从命令行运行代码(或将 command$ 参数修改为 QB64 菜单)获得了 10 多个循环:

# ./test n

n 是您想要的循环数。

软件是使用带有 -O3 优化选项的 gcc 编译的。 (为此,您必须修改文件[/opt/]qb64/internal/c/makeline_lnx.txt

【讨论】:

感谢测试!我认为会有很小或没有区别...... 我认为没有区别,因为编译if value的最简单(唯一)方法应该基于if value&lt;&gt;0 或者如果编译器将if value&lt;&gt;0 then优化为If value then 如果你进入非常低的级别,你可能会想象在 asm x86 中你有(在两种情况下)相同的代码,大致:cmp ds:[ebx],0; jnz label; call printf; label: ... 我认为 C++ 编译器也会优化 C=C+1 和 C+=1 以及 C++。

以上是关于QB64 中的循环优化的主要内容,如果未能解决你的问题,请参考以下文章

用三菱plc循环位移指令做8灯循环梯形图

优化 iOS 应用的迭代 for 循环 [关闭]

确保字符串的第一个字符在 QB64 中是大写的

优化 FOR 循环中的请求

结构与算法一元多项式的相加运算

c#中的循环优化