运行时与编译时间


Answers:


479

编译时间和运行时间之间的差异是尖锐的理论家称之为相位区别的一个例子。这是最难学习的概念之一,特别是对于那些没有太多编程语言背景的人而言。为了解决这个问题,我觉得问一下很有帮助

  1. 程序满足什么不变式?
  2. 在此阶段可能出什么问题?
  3. 如果阶段成功,那么后置条件是什么(我们知道什么)?
  4. 输入和输出(如果有)是什么?

编译时间

  1. 该程序不必满足任何不变式。实际上,它根本不是一个格式正确的程序。您可以将此HTML提交给编译器,然后看一下它的barf ...
  2. 编译时可能出问题的地方:
    • 语法错误
    • 类型检查错误
    • (很少)编译器崩溃
  3. 如果编译成功,我们怎么知道?
    • 该程序格式正确-不管使用哪种语言,它都是有意义的程序。
    • 可以开始运行该程序。(该程序可能会立即失败,但至少我们可以尝试。)
  4. 输入和输出是什么?
    • 输入的内容是正在编译的程序,以及为进行编译而需要导入的任何头文件,接口,库或其他伏都教。
    • 希望输出是汇编代码或可重定位的目标代码,甚至是可执行程序。或者,如果出现问题,则输出是一堆错误消息。

运行

  1. 我们对程序的不变式一无所知-它们与程序员所投入的一样。它需要程序员的帮助。
  2. 可能出错的是运行时错误

    • 被零除
    • 解引用空指针
    • 内存不足

    此外,程序本身也可能检测到错误:

    • 尝试打开不存在的文件
    • 尝试查找网页并发现所指控的网址格式不正确
  3. 如果运行时成功,程序将完成(或继续运行)而不会崩溃。
  4. 输入和输出完全取决于程序员。您将文件,屏幕上的窗口,网络数据包,发送到打印机的作业命名。如果程序发射导弹,那是输出,并且仅在运行时发生:-)

13
它涵盖了(+1)的很好的答案,但是您甚至没有涉及编译时与运行时的元编程方面,恕我直言,这是最有趣的部分。鉴于此答案被接受,我会同意,这很可能超出了OP的要求。
BCS

4
很好,如果有人在我的演讲中问我有关问题,我将使用您的答案:-)
e-satis

12
这是一个非常好的答案。这是非常清楚和易于理解的。在Google中找到如此清晰的答案并不容易。
塔里克2009年

7
即使您已经编程了一会儿,仍然很难获得……不仅是新手。OP的好问题。
PositiveGuy

11
“该程序不必满足任何不变式。实际上,它根本不需要是格式正确的程序。您可以将此HTML馈送到编译器,然后看一下它的barf ...”,我不知道您在说什么这里。您能用简单的术语来解释这一点,而不会被所有这些技术垃圾所困扰吗?
PositiveGuy

175

我从错误以及何时发现错误的角度来考虑它。

编译时间:

string my_value = Console.ReadLine();
int i = my_value;

不能为字符串值分配int类型的变量,因此编译器在编译时肯定知道此代码有问题。

运行:

string my_value = Console.ReadLine();
int i = int.Parse(my_value);

这里的结果取决于ReadLine()返回的字符串。某些值可以解析为int,而其他则不能。这只能在运行时确定


59
现在,我们都可以理解这一点。这里没有一般的垃圾技术词汇。真好
PositiveGuy

对于iPhone App:是开发人员第一次将代码编译为.app扩展时的编译时间吗?还是每次用户启动应用启动时发生?
亲爱的

1
@Honey它被编译第一次通过显影剂进入的.app
maytham-ɯɐɥʇʎɐɯ

2
这是一个很好的底线答案,从概念上涵盖了编译时间和运行时间之间的差异。我也很欣赏选择的学术,教授答案,但是这个答案简洁明了。阅读此答案后,我可以返回并阅读所选的答案,这更有意义。谢谢
mojave

72

编译时间:您(开发人员)用来编译代码的时间段。

运行时间:用户运行您的软件的时间段。

您需要更清晰的定义吗?


12
@BCS:OP可能使用解释型或字节编译然后一步一步运行的语言对编程进行了非常简单的介绍,因此无需区分。天真的问题,但不是愚蠢的。
dmckee ---前主持人小猫

@dmckee:我认为这个答案甚至对您的用户都没有用,因为它没有比原始问题更多的信息内容。任何想问这个答案可以回答的问题的人都没有业务编程(我认为OP在问这个问题)。
BCS

我有一个快速的问题。当有人说典型的运行时错误被零除,但是如果您有一个变量int x = 3/0该怎么办,可以说,但是您对此变量不做任何事情。我们不打印它或任何东西。仍将其视为运行时错误吗?
罗本

对于iPhone App:是开发人员第一次将代码编译为.app扩展名时的编译时间吗?还是在每次用户启动应用时启动时发生?如果是在编译开发人员代码的编译时间,那我为什么要关心它呢?我的意思是这不会影响用户体验吗?因为这只会浪费开发人员的时间!
亲爱的2016年

1
@Robben我想你已经这么长的时间后,得到的答案,但我会回答它others.yes这将是一个运行时错误,即使你不使用它
فربدضروري

22

编辑:以下内容适用于C#和类似的强类型编程语言。我不确定这是否对您有帮助)。

例如,在运行程序之前,编译器将在编译时检测到以下错误,并导致编译错误:

int i = "string"; --> error at compile-time

另一方面,编译器无法检测到以下错误。您将在运行时(程序运行时)收到错误/异常。

Hashtable ht = new Hashtable();
ht.Add("key", "string");
// the compiler does not know what is stored in the hashtable
// under the key "key"
int i = (int)ht["key"];  // --> exception at run-time

例外情况。哈希表是其中之一,但我发现最大的一步是从.net 1.1到.net 2.0,从无类型数据集变为有类型数据集(现在为linq)。试图用一个狡猾的数据库解决一个损坏的表格,这让我非常难过!
斯彭斯

19

将源代码转换为发生在[screen | disk | network]上的东西有两种方法(大致)。称他们为编译和解释。

在已编译的程序中(示例为c和fortran):

  1. 源代码被馈送到另一个程序(通常称为编译器),该程序将生成可执行程序(或错误)。
  2. 运行该可执行文件(通过双击该可执行文件,或在命令行上输入其名称)

第一步中发生的事情据说是在“编译时”发生的,第二步中发生的事情是据说在“运行时”发生的。

解释程序中(示例MicroSoft basic(在dos上)和python(我认为)):

  1. 源代码被馈送到另一个程序(通常称为解释器),该程序直接“运行”它。在这里,解释器充当程序和操作系统(或非常简单的计算机中的硬件)之间的中间层。

在这种情况下,编译时间和运行时间之间的差异很难确定,并且与程序员或用户无关。

Java是一种混合程序,其中代码被编译为字节码,然后在虚拟机上运行,​​该虚拟机通常是字节码的解释器。

还有一种中间情况,其中程序被编译为字节码并立即运行(如在awk或perl中)。


11

基本上,如果您的编译器可以弄清楚您的意思或“编译时”的值,则可以将其硬编码为运行时代码。显然,如果您的运行时代码每次都必须执行一次计算时,运行速度就会变慢,因此,如果您可以在编译时确定某些内容,那就更好了。

例如。

恒定折叠:

如果我写:

int i = 2;
i += MY_CONSTANT;

编译器可以在编译时执行此计算,因为它知道2是什么,什么是MY_CONSTANT。这样,它可以避免每次执行都执行计算。


而且,维护编译时代码比运行时绑定代码容易。在编译时,您可以使用编译器检查某些内容。在运行时,相同的内容需要花费更多的时间检查,因为涉及测试。
user1154664

10

嗯,好的,运行时用于描述程序运行时发生的事情。

编译时间用于描述在构建程序时(通常是由编译器)发生的事情。


8

编译时间:

在运行结果程序时,在编译时完成的事情几乎不会产生任何费用,但是在生成程序时可能会产生很大的费用。

运行:

恰恰相反。构建时成本很小,运行程序时成本更高。

从另一面看 如果某件事在编译时完成,则仅在您的计算机上运行,​​如果某事在运行时,则在您的用户计算机上运行。

关联

一个重要的例子是单位运载类型。最终,编译时版本(例如Boost.UnitsD中的我的版本)的运行速度与解决本机浮点代码的问题一样快,而运行时版本最终不得不打包有关值的单位的信息并在每个操作旁边对它们进行检查。另一方面,编译时版本要求值的单位在编译时是已知的,并且不能处理它们来自运行时输入的情况。


8

从前面类似的问题答案中可以得出以下结论:运行时错误和编译器错误有什么区别?

编译/编译时间/语法/语义错误:编译或编译时间错误是由于键入错误而引起的错误,如果我们未遵循任何编程语言的正确语法和语义,则编译器将抛出编译时间错误。在删除所有语法错误或调试编译时错误之前,它们不会让您的程序执行一行。
示例:缺少C的分号或错误int地输入Int

运行时错误:运行时错误是程序处于运行状态时生成的错误。这些类型的错误将导致您的程序表现异常,甚至可能导致您的程序死亡。它们通常称为异常。
示例:假设您正在读取一个不存在的文件,将导致运行时错误。

在此处详细了解所有编程错误


7

作为其他答案的补充,这是我向外行解释的方式:

您的源代码就像一艘船的蓝图。它定义了船只的制造方式。

如果您将蓝图交给造船厂,而他们在造船时发现有缺陷,他们将停止造船,并在船舶离开船坞或接触水之前立即向您报告。这是一个编译时错误。该船甚至从未真正漂浮或使用其引擎。发现该错误是因为它甚至阻止了该船的制造。

当您的代码编译时,就好像飞船已经完成了。已建成并准备就绪。当您执行代码时,就像在远航中发射飞船一样。登上乘客,发动机在运转,船体在水上,所以这是运行时间。如果您的船有致命的缺陷使它在首次航行中沉没(或者可能在以后的航行中感到头疼),那么它将遭受运行时错误。


5

例如:在强类型语言中,可以在编译时或运行时检查类型。在编译时,这意味着编译器会抱怨类型是否不兼容。在运行时意味着您可以很好地编译程序,但是在运行时会引发异常。


4

简而言之,是b / w编译时间和运行时间。

编译时间:开发人员以.java格式编写程序并将其转换为作为类文件的Bytecode,在此编译期间发生的任何错误都可以定义为编译时错误。

运行时:生成的.class文件被应用程序使用,以实现其附加功能,并且逻辑证明是错误的,并引发错误,这是运行时错误


4

这是“ JAVA编程简介”一书的作者Daniel Liang关于编译的引文:

“用高级语言编写的程序称为源程序或源代码。由于计算机无法执行源程序,因此必须将源程序转换机器代码执行。可以使用另一种编程工具来完成该转换。解释器或编译器。” (Daniel Liang,“ JAVA编程简介”,第8页)。

...他继续...

“编译器将整个源代码转换为机器代码文件,然后执行机器代码文件”

首先,当我们打入高级/人类可读的代码时,这毫无用处!它必须在您的小CPU上转换为一系列“电子事件”!第一步是编译。

简而言之:在此阶段会发生编译时错误,而稍后会发生运行时错误。

切记:仅仅因为程序编译没有错误并不意味着它会正确运行。

在程序生命周期的就绪,运行或等待部分中将发生运行时错误,而在生命周期的“新”阶段之前将发生编译时错误。

编译时错误的示例:

语法错误-如果代码不明确,如何将它们编译为机器级指令?您的代码需要100%符合该语言的语法规则,否则无法将其编译为有效的机器代码

运行时错误的示例:

内存不足-给定特定程度的变量,例如调用递归函数可能会导致堆栈溢出!编译器如何预料到这一点!这不可以。

那就是编译时错误和运行时错误之间的区别


2

运行时意味着在运行程序时发生了某些事情。

编译时意味着编译程序时发生了某些事情。


2

编译时间:

在运行结果程序时,在编译时完成的事情几乎不会产生任何成本,但是在生成程序时可能会产生很大的成本。运行:

恰恰相反。构建时成本很小,运行程序时成本更高。

从另一面看 如果某件事在编译时完成,则仅在您的计算机上运行,​​如果某事在运行时,则在您的用户计算机上运行。


2

编译时间: 将源代码转换为机器代码以使其成为可执行文件所花费的时间称为编译时间。

运行时: 当应用程序运行时,称为运行时。

编译时错误是那些语法错误,缺少文件引用错误。在将源代码编译成可执行程序之后,并且在程序运行时会发生运行时错误。例如程序崩溃,程序意外行为或功能不起作用。


2

假设您是老板,有一个助手和一个女佣,并且给他们列出了要执行的任务,助手(编译时)将抓住这个列表并进行检查,以查看任务是否可以理解以及您没有用任何尴尬的语言或语法写东西,所以他了解到您想为某人分配一份工作,因此他为您分配了他,并且他了解您想要一些咖啡,因此他的角色结束了,女仆(运行时)开始执行这些任务,以便她去为您煮咖啡,但是突然间,她找不到要煮的咖啡,因此她停止煮咖啡,或者以不同的方式为您泡茶(当程序因他发现错误而以不同的方式进行操作时) )。


1

这是对“运行时与编译时之间的差异?”问题的答案的扩展。- 管理费用差异与运行时和编译时相关的?

产品的运行时性能可通过更快地交付结果来提高其质量。该产品的编译时性能通过缩短编辑-编译-调试周期来提高其及时性。但是,运行时性能和编译时性能都是获得及时质量的次要因素。因此,只有在整体产品质量和及时性得到改善的情况下,才应考虑运行时和编译时性能的改善。

在这里进一步阅读的好资料:


1

我一直在考虑与程序处理开销有关的问题,以及它如何影响性能(如前所述)。一个简单的示例就是,是否用代码定义对象的绝对内存。

定义的布尔值占用x内存,这是已编译程序中的内容,无法更改。程序运行时,它确切知道要为x分配多少内存。

另一方面,如果我仅定义通用对象类型(即,一种未定义的占位符或指向某个巨型Blob的指针),则在程序运行并为其分配某些内容之前,该对象所需的实际内存是未知的,因此必须对其进行评估,然后将在运行时动态处理内存分配等(更多的运行时开销)。

动态处理方式将取决于语言,编译器,操作系统,您的代码等。

但是,实际上,这实际上取决于您使用运行时与编译时的上下文。


1

我们可以将它们分为静态绑定和动态绑定两大类。它基于何时使用相应的值完成绑定。如果引用在编译时解析,则为静态绑定,如果引用在运行时解析,则为动态绑定。静态绑定和动态绑定也称为早期绑定和晚期绑定。有时它们也被称为静态多态和动态多态。

约瑟夫·库兰代。


1

运行时和编译时间之间的主要区别是:

  1. 如果您的代码中有语法错误并进行类型检查,则会引发编译时错误,其中-运行时:在执行代码后进行检查。例如:

int a = 1 int b = a/0;

这里第一行最后没有分号--->在执行操作b的同时执行程序后,编译时错误,结果是无限--->运行时错误。

  1. 编译时不查找代码提供的功能输出,而运行时查找。

1

这是一个非常简单的答案:

运行时和编译时是编程术语,指的是软件程序开发的不同阶段。为了创建程序,开发人员首先编写源代码,该源代码定义了程序将如何运行。小型程序可能仅包含几百行源代码,而大型程序可能包含数十万行源代码。必须将源代码编译为机器代码才能成为可执行程序。此编译过程称为编译时间。(将编译器视为翻译器)

编译的程序可以由用户打开和运行。当应用程序正在运行时,它称为运行时。

程序员经常使用术语“运行时”和“编译时”来指代不同类型的错误。编译时错误是诸如语法错误或文件引用丢失之类的问题,它们阻止程序成功进行编译。编译器会产生编译时错误,并且通常会指出导致问题的源代码行。

如果程序的源代码已经被编译为可执行程序,则在程序运行时它可能仍然会出现错误。示例包括无法使用的功能,程序意外行为或程序崩溃。这些类型的问题称为运行时错误,因为它们在运行时发生。

参考资料


0

恕我直言,您需要阅读许多链接和资源,以了解运行时与编译时之间的时差,因为这是一个非常复杂的主题。我在下面列出了一些我推荐的图片/链接。

除了上面所说的,我想补充一点,有时一张价值1000字的图片:

  1. 这两个命令的顺序:首先是编译时,然后您运行一个已编译的程序可以由用户打开并运行。当应用程序运行时,它称为runtime:编译时,然后runtime1 编译时间,然后运行1

CLR_diag编译时间,然后运行时2  CLR_diag编译时间,然后运行时2

 from Wiki  

https://zh.wikipedia.org/wiki/运行时间 https://zh.wikipedia.org/wiki/运行时间(program_lifecycle_phase)

运行时,运行时或运行时可以指的是:

电脑运算

运行时间(程序生命周期阶段),计算机程序执行的时间

运行时库,一种程序库,旨在实现内置于编程语言中的功能

运行系统,旨在支持计算机程序执行的软件

软件执行,在运行时阶段一一执行指令的过程

在此处输入图片说明 在此处输入图片说明

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 编译器列表 https://en.wikipedia.org/wiki/List_of_compilers在此处输入图片说明 在此处输入图片说明

  • 在Google上搜索并比较运行时错误与编译错误:

运行时错误

编译错误 ;

  1. 在我看来,要知道一个非常重要的事情:3.1构建与编译与构建生命周期之间的区别 https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

3.2这三件事之间的区别:编译vs构建vs运行时

https://www.quora.com/What-is-the-difference-between-build-run-and-compile 费尔南多·帕多安(Fernando Padoan),对语言设计有点好奇的开发人员回答2月23日我倒退了其他答案:

运行正在使某个二进制可执行文件(或用于解释语言的脚本)被很好地作为计算机上的新进程执行;编译是以下过程的过程:解析以某种高级语言编写的程序(与机器代码相比更高),检查其语法,语义,链接库,也许进行一些优化,然后创建一个二进制可执行程序作为输出。该可执行文件可以采用机器代码或某种字节代码的形式-即针对某种虚拟机的指令;构建通常包括检查和提供依赖项,检查代码,将代码编译为二进制文件,运行自动化测试并将生成的二进制文件和其他资产(图像,配置文件,库等)打包为某种特定格式的可部署文件。请注意,大多数过程是可选的,某些过程取决于您要构建的目标平台。例如,为Tomcat打包Java应用程序将输出一个.war文件。用C ++代码构建Win32可执行文件可以只输出.exe程序,也可以将其打包在.msi安装程序中。


0

看这个例子:

public class Test {

    public static void main(String[] args) {
        int[] x=new int[-5];//compile time no error
        System.out.println(x.length);
    }}

上面的代码已成功编译,没有语法错误,完全有效。但是在运行时,它会引发以下错误。

Exception in thread "main" java.lang.NegativeArraySizeException
    at Test.main(Test.java:5)

就像在编译时检查了某些情况一样,在运行时间过后,一旦程序满足所有条件,您就已经检查了某些情况,您将获得输出。否则,您将获得编译时或运行时错误。


0

公共类RuntimeVsCompileTime {

public static void main(String[] args) {

    //test(new D()); COMPILETIME ERROR
    /**
     * Compiler knows that B is not an instance of A
     */
    test(new B());
}

/**
 * compiler has no hint whether the actual type is A, B or C
 * C c = (C)a; will be checked during runtime
 * @param a
 */
public static void test(A a) {
    C c = (C)a;//RUNTIME ERROR
}

}

class A{

}

class B extends A{

}

class C extends A{

}

class D{

}


0

通过阅读实际代码,您可以了解代码编译结构。除非您了解所使用的模式,否则运行时结构尚不清楚。


-1

对于SO来说,这不是一个好问题(这不是一个特定的编程问题),但总的来说,这不是一个坏问题。

如果您认为这很琐碎:那么读取时间与编译时间又如何呢?什么时候才是有用的区分呢?在运行时可以使用编译器的语言呢?盖伊·斯蒂尔(Guy Steele,他不是虚拟人)在CLTL2中写了7页关于EVAL-WHEN的页面,CL程序员可以用它来控制此情况。2个句子几乎不足以给出一个定义,而定义本身远远不够解释

通常,语言设计师似乎一直在努力避免这个难题。他们经常说“这是一个编译器,它可以完成编译时的事情;在此之后的所有事情都可以在运行时玩得开心”。C被设计为易于实现,而不是最灵活的计算环境。如果您在运行时没有可用的编译器,或者无法轻松控制对表达式进行评估的能力,则您最终会遭受该语言的黑客攻击,以伪造宏的常用用法,或者用户想出了设计模式来进行仿真具有更强大的结构。易于实现的语言绝对是一个值得追求的目标,但这并不意味着它就是编程语言设计的全部。(我很少使用EVAL-WHEN,但是如果没有它,我无法想象生活。)

而且,围绕编译时和运行时的问题空间很大,并且仍在很大程度上未被开发。这并不是说SO是进行讨论的合适地点,但我鼓励人们进一步探索这个领域,尤其是那些对应该做什么应该有先入为主的概念的人们。这个问题既不简单也不愚蠢,我们至少可以将调查者指向正确的方向。

不幸的是,我对此没有任何好的参考。CLTL2讨论了一下,但是对于学习它并不是很好。


4
老兄对你来说不是一个好的编程问题是相对的。我认为这是一个很好的问题,我想进一步了解。是的,我知道一般的“概念”以及什么是编译时和运行时,但是我想知道在运行时与编译时真正发生的麻烦。当您编程并需要意识到这些琐事时才重要。这不是很具体,所以这就是他问的原因。当人们坐在这里说诸如此类的一般性问题是任何开发人员都必须掌握的最重要的问题时,我讨厌它。
PositiveGuy

1
如果您没有看到问题的价值,那就是您的问题。如果很一般,那是有原因的。仅仅因为您不喜欢一般性问题,并不意味着世界就围绕您认为有用的事物旋转。他有一定的意图要问这个问题,并且他想提供一系列答案以更好地理解和定义这两个问题。得到它?
PositiveGuy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.