为什么TI-Basic很慢?

6

我决定编写一个程序,可以找到任意两个数(包括非整数)的最大公约数,使用TI-Basic语言。在Java中,我已经成功地使用了这个程序,所以我知道它是能工作的。虽然它在TI-Basic中也能正常工作,但与内置的gcd(函数相比,它非常缓慢。gcd(函数似乎只需要毫秒级别的时间就能得到结果,而我的程序可能需要几秒钟。 为什么TI-Basic比预定义的计算器函数慢那么多?

代码


下面是该程序的TI-Basic代码供您查看:

PROGRAM:GCD

:ClrHome
:Disp "Greatest Common","    Divisor","      ---"
:Input "First number? ",X
:Input "Second number? ",Y
:
:X→I
:Y→J
:
:If (I≠int(I) or J≠int(J))
:Then
:ClrHome
:Disp "Non-integer","inputs may be","innacurate!",""
:End
:If (I=1 or J=1)
:Then
:1→I
:1→J
:Goto Z
:End
:For(C,0,2^8)
:If I=J
:Goto Z
:
:If I>J
:I-J→I
:
:If J>I
:J-I→J
:
:End
:
:Disp "This is a hard","one! Thinking","harder..."
:
:For(C,0,2^15)
:If (I=J)
:Goto Z
:While (I>J)
:I-J→I
:C+1→C
:End
:While (J>I)
:J-I→J
:C+1→C
:End
:End
:
:Disp "TIMED OUT!","Either:",J,"or"
:Pause
:
:Lbl Z
:ClrHome
:Disp "GCD of",X,"and",Y,"is",I

免责声明:这是我在查看我的TI-84并将其输入到此处的结果。可能会有一些错别字,但我尽力保持它相同。

对于那些不知道这意味着什么的人,下面提供了伪代码:

program gcd()
{
Console.clear();
Console.writeln("Greatest Common");
Console.writeln("    Divisor");
Console.writeln("      ---");

float X = Console.readFloat("First Number? ");
float Y = Console.readFloat("Second number? ");

float I = X;
float J = Y;

if (I != (int)I || J != (int)J)
{
  Console.clear();
  Console.writeln("Non-integer");
  Console.writeln("inputs may be");
  Console.writeln("inaccurate!");
  Console.writeln("");
}
if (I == 1 or J == 1)
{
  I = 1;
  J = 1;
  goto Z;
}

for(int C = 0, limit = Math.pow(2,8); C < limit; C++)
{
  if (I == J)
    goto Z;

  if (I > J)
    I = I - J;

  if (J > I)
    J = J - I;
}

Console.writeln("This is a hard");
Console.writeln("one! Thinking");
Console.writeln("harder...");

for(int C = 0, limit = Math.pow(2,15); C < limit; C++)
{
  if (I == J)
    goto z;
  while (I > J)
  {
    I = I - J;
    C++;
  }
  while (J>I)
  {
    J = J-I;
    C++;
  }
}

Console.writeln("TIMED OUT!");
Console.writeln("Either:");
Console.writeln(J);
Console.writeln("or");
Console.pause();

Z:
Console.clear();
Console.writeln("GCD of");
Console.writeln(X);
Console.writeln("and");
Console.writeln(Y);
Console.writeln("is");
Console.writeln(I);
}

1
limit=Math.pow(2,8) 这段代码在循环的每一次迭代中都会重新解释执行,可能会发生数十次、数百次甚至上千次。这样做效率较低,因为你的代码不如 gcd 源代码高效。 - Eric Leschinski
2
@EricLeschinski,你的理解有误。请注意,只有在声明limit时才会调用它,并且它的返回值会立即存储在limit中。之后,在每个循环中,只会从limit中读取该值。不过,你的观察力真不错! - Ky -
哦,天啊,TI-Basic。这让我回忆起了过去。 - Mike G
3个回答

11

由于它是一种解释型语言,速度较慢 -解释型语言的缺点。

基本上,这会影响到获取用户输入和在屏幕上显示图形。


但它真的会慢那么多吗?我的意思是,我们在这里谈论的是分钟与毫秒之间的差别。 - Ky -
5
好的。请访问http://tibasicdev.wikidot.com/whytibasic了解有关TI的详细说明,并访问http://tibasicdev.wikidot.com/optimize-loops获取有关如何优化程序(而无需在汇编中重写)的信息。 - Philip
1
谢谢提供这些链接!我已经知道了,但是没有想到它会有这么大的影响。从现在开始我会牢记在心的;D - Ky -

2

2
谢谢。七年的软件工程经验教会了我很多东西,我很高兴你在这个问题上做了笔记,以防未来的读者不知道。 - Ky -

1
另一个导致速度缓慢的原因是clrHome,我意识到在使用它们时,clr-home需要一段时间才能完成,可能需要半秒钟,至少在Ti-83 Plus上是这样,通常dispinput不需要多少时间,而且你也可以使用prompt first number','second number'代替两个输入。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接