运行时与编译时间

时间:2009-05-10 21:06:35

标签: runtime compile-time

任何人都可以让我很好地理解运行时和编译时的区别是什么?

27 个答案:

答案 0 :(得分:431)

编译时和运行时之间的差异是一个尖头理论家称之为 phase distinction 的例子。这是最难学习的概念之一,特别是对于没有很多编程语言背景的人。为了解决这个问题,我发现提问

很有帮助
  1. 程序满足哪些不变量?
  2. 这个阶段可能出现什么问题?
  3. 如果阶段成功,后置条件是什么(我们知道什么)?
  4. 输入和输出是什么?
  5. 编译时间

    1. 程序不需要满足任何不变量。事实上,它根本不需要是一个结构良好的程序。您可以将此HTML提供给编译器并观察它barf ...
    2. 编译时可能出现的问题:
      • 语法错误
      • Typechecking错误
      • (很少)编译器崩溃
    3. 如果编译器成功,我们知道什么?
      • 该计划形成良好 - 无论使用何种语言都是一个有意义的计划。
      • 可以开始运行程序。 (该程序可能会立即失败,但至少我们可以尝试。)
    4. 输入和输出是什么?
      • 输入是正在编译的程序,以及导入以便编译所需的任何头文件,接口,库或其他伏都教。
      • 希望输出汇编代码或可重定位目标代码甚至可执行程序。或者如果出现问题,输出就是一堆错误消息。
    5. 运行时间

      1. 我们对程序的不变量一无所知 - 它们是程序员所放的任何东西。运行时不变量很少由编译器强制执行;它需要程序员的帮助。
      2. 运行时错误

        可能出现的问题
        • 除以零
        • 取消引用空指针
        • 内存不足

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

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

答案 1 :(得分:152)

我从错误的角度考虑它,以及何时可以捕获它们。

编译时间:

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

无法为字符串值分配int类型的变量,因此编译器确定在编译时该代码存在问题

运行时间:

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

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

确定

答案 2 :(得分:60)

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

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

您需要更明确的定义吗?

答案 3 :(得分:21)

编辑:以下内容适用于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

答案 4 :(得分:18)

将源代码翻译成[屏幕|磁盘|网络]上发生的事情可以(大致)以两种方式进行;叫他们编译和解释。

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

  1. 源代码被送入另一个程序(通常称为编译器 - 转换图),产生可执行程序(或错误)。
  2. 运行可执行文件(通过双击它,或在命令行上键入它的名称)
  3. 第一步发生的事情据说发生在“编译时”,第二步发生的事情据说发生在“运行时”。

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

    1. 源代码被送入另一个程序(通常称为解释器),直接“运行”它。这里的解释器充当程序和操作系统(或非常简单的计算机中的硬件)之间的中间层。
    2. 在这种情况下,编译时和运行时之间的差异很难确定,而与程序员或用户的相关性则更低。

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

      还有一个中间案例,程序被编译为字节码并立即运行(如awk或perl)。

答案 5 :(得分:11)

基本上,如果您的编译器可以解决您的意思或“在编译时”的值是什么,它可以将其硬编码到运行时代码中。显然,如果运行时代码每次运行速度较慢时都必须进行计算,那么如果你能在编译时确定一些东西,那就更好了。

例如

恒定折叠:

如果我写:

int i = 2;
i += MY_CONSTANT;

编译器可以在编译时执行此计算,因为它知道2是什么,以及MY_CONSTANT是什么。因此,它不会在每次执行时执行计算。

答案 6 :(得分:8)

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

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

答案 7 :(得分:8)

编译时间:

在生成程序时,在编译时完成的事情(几乎)不会产生任何成本,但在构建程序时可能会产生很大的成本。

运行时:

或多或少恰恰相反。构建时成本很低,程序运行时成本更高。

从另一边;如果在编译时完成某些操作,它只在您的计算机上运行,​​如果某些内容是运行时,它将在您的用户计算机上运行。

关联

这很重要的一个例子是单位携带类型。编译时版本(如Boost.Unitsmy version in D)最终与使用本机浮点代码解决问题一样快,而运行时版本最终必须打包有关单元的信息每个操作都有一个值并在其中执行检查。另一方面,编译时版本需要在编译时知道值的单位,并且不能处理它们来自运行时输入的情况。

答案 8 :(得分:8)

根据之前类似的问题What is the difference between run-time error and compiler error?

回答

编译/编译时间/语法/语义错误:编译或编译时错误是由于输入错误导致的错误,如果我们不遵循任何编程语言的正确语法和语义然后编译时间编译器抛出错误。在删除所有语法错误或调试编译时错误之前,他们不会让程序执行单行 示例:在C中缺少分号或将int误导为Int

运行时错误:运行时错误是程序处于运行状态时生成的错误。这些类型的错误将导致程序出现意外行为或甚至可能导致程序中断。它们通常被称为例外 示例:假设您正在读取不存在的文件,将导致运行时错误。

详细了解此处的所有programming errors

答案 9 :(得分:5)

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

答案 10 :(得分:5)

作为其他答案的附加内容,以下是我如何向外行解释:

您的源代码就像一艘船的蓝图。它定义了如何制造船舶。

如果你把你的蓝图交给造船厂,并且他们在建造船舶时发现了缺陷,他们会在船离开干船坞或接触水之前立即停止建造并向你报告。这是编译时错误。这艘船甚至从未真正浮动或使用其发动机。发现错误是因为它阻止了船舶的制造。

当您的代码编译时,它就像船只完成一样。建成并准备好了。执行代码时,就像在航行中启动船只一样。乘客登机,发动机正在运行,船体在水面上,所以这是运行时间。如果你的船有一个致命的缺陷,在它的处女航中沉没(或者可能是因为额外的头痛之后的一些航行),那么它会遇到运行时错误。

答案 11 :(得分:4)

以下是关于编译主题的“JAVA编程简介”一书作者Daniel Liang的引用:

  

“用高级语言编写的程序称为源程序或源代码。由于计算机无法执行源程序,源程序必须已翻译机器代码中 执行。可以使用另一种称为解释器或编译器的编程工具完成翻译。 (Daniel Liang,"Introduction to JAVA programming",第8页)。

......他继续......

  

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

当我们使用高级/人类可读的代码时,这首先是无用的!它必须在你的小CPU中翻译成一系列“电子事件”!迈向此的第一步是编译。

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

请记住:仅仅因为程序编译时没有错误并不意味着它会毫无错误地运行。

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

编译时错误示例:

语法错误 - 如果代码不明确,如何将代码编译成机器级指令?您的代码需要100%符合该语言的语法规则,否则无法编译为工作machine code

运行时错误示例:

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

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

答案 12 :(得分:4)

简单的字差b / w编译时间&运行时间。

编译时间:开发人员以.java格式编写程序&转换为类文件字节码,在编译期间,任何错误都可以定义为编译时错误。

运行时:应用程序使用生成的.class文件来获取其附加功能&逻辑结果是错误的并抛出错误,这是一个运行时错误

答案 13 :(得分:2)

编译时间:

在生成程序时,在编译时完成的任务(几乎)不会产生任何成本,但在构建程序时可能会产生很大的成本。 运行时:

或多或少恰恰相反。构建时成本很低,程序运行时成本更高。

从另一边;如果在编译时完成某些操作,它只在您的计算机上运行,​​如果某些内容是运行时,它将在您的用户计算机上运行。

答案 14 :(得分:2)

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

运行时间 当应用程序运行时,它被称为运行时。

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

答案 15 :(得分:2)

运行时意味着运行程序时会发生一些事情。

编译时意味着在编译程序时会发生一些事情。

答案 16 :(得分:1)

看这个例子:

blue

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

content 3a, 3b, 3c, 3d

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

答案 17 :(得分:1)

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

答案 18 :(得分:1)

我一直认为它与程序处理开销有关,以及它如何影响前面所述的性能。一个简单的例子是,或者在代码中定义我的对象所需的绝对内存。

定义的布尔值占用x内存,然后在编译的程序中,不能更改。当程序运行时,它确切地知道为x分配多少内存。

另一方面,如果我只定义一个通用对象类型(即一种未定义的占位符或者可能指向某个巨型blob的指针),在程序运行之前我的对象所需的实际内存是不可知的然后必须对它进行评估,然后在运行时动态处理内存分配等(更多的运行时间开销)。

如何动态处理它将取决于语言,编译器,操作系统,代码等。

然而,在这方面,它实际上取决于您使用运行时间与编译时间的上下文。

答案 19 :(得分:1)

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

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

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

术语"运行时"和#34;编译时间"程序员经常使用它来引用不同类型的错误。编译时错误是一个问题,例如语法错误或缺少文件引用,导致程序无法成功编译。编译器会产生编译时错误,通常会指示导致问题的源代码行。

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

The reference

答案 20 :(得分:1)

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

  1. 如果您的代码中存在任何语法错误和类型检查,则会抛出编译时错误,其中 - 作为运行时:它在执行代码后进行检查。 例如:
  2. int a = 1 int b = a/0;

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

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

答案 21 :(得分:1)

我们可以在不同的两大组静态绑定和动态绑定下对这些进行分类。它基于何时使用相应的值进行绑定。如果在编译时解析引用,则它是静态绑定,如果在运行时解析引用,则它是动态绑定。静态绑定和动态绑定也称为早期绑定和后期绑定。有时它们也被称为静态多态和动态多态。

Joseph Kulandai。

答案 22 :(得分:1)

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

产品的运行时性能通过更快地提供结果来提高其质量。产品的编译时性能通过缩短编辑 - 编译 - 调试周期来提高其及时性。但是,运行时性能和编译时性能都是实现及时质量的次要因素。因此,只有通过改进整体产品质量和及时性,才能考虑运行时和编译时性能改进。

进一步阅读here的重要来源:

答案 23 :(得分:0)

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

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

  1. 这两个的顺序:首先是编译时间,然后运行 编译的程序可以由用户打开和运行。当应用程序运行时,它被称为运行时: 编译时间然后运行run1 compile time and then runtime1;
  2. CLR_diag编译时间然后运行时2  CLR_diag compile time and then runtime2

     from Wiki  
    

    https://en.wikipedia.org/wiki/Run_time https://en.wikipedia.org/wiki/Run_time_(program_lifecycle_phase)

    运行时,运行时或运行时可以参考:

    计算

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

    运行时库,一个旨在实现编程语言内置函数的程序库

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

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

    enter image description here enter image description here

    enter image description here enter image description here enter image description here  enter image description here enter image description here 编译器列表 enter image description here  enter image description here https://en.wikipedia.org/wiki/List_of_compilers

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

    runtime errors

    compile errors;

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

      https://www.quora.com/What-is-the-difference-between-build-run-and-compile Fernando Padoan,一位对语言设计有点好奇的开发人员 2月23日回答 我将与其他答案相关:

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

答案 24 :(得分: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{

}

答案 25 :(得分:0)

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

答案 26 :(得分:-1)

这对S.O.来说不是一个好问题。 (这不是一个特定的编程问题),但一般来说这不是一个坏问题。

如果您认为这是微不足道的:读取时间与编译时间有何关系,何时这是一个有用的区别?那些编译器在运行时可用的语言呢? Guy Steele(没有假人,他)在CLTL2中写了7页关于EVAL-WHEN的内容,CL程序员可以使用它来控制它。 2个句子对于定义来说勉强够用,它本身远远没有解释

总的来说,语言设计师似乎试图避免这是一个棘手的问题。 他们经常只说“这是一个编译器,它确实是编译时间的东西;之后的所有东西都是运行时,玩得开心”。 C旨在实现简单,而不是最灵活的计算环境。如果您没有在运行时使用编译器,或者能够轻松控制何时评估表达式,那么您最终会使用语言中的黑客来伪造宏的常见用法,或者用户想出了设计模式来模拟拥有更强大的结构。一个易于实现的语言绝对是一个有价值的目标,但这并不意味着它是最终所有的编程语言设计。 (我不使用EVAL-WHEN,但我无法想象没有它的生活。)

编译时和运行时的问题空间很大,但仍然很大程度上尚未开发。那不是说S.O.是进行讨论的合适场所,但我鼓励人们进一步探索这片领域,特别是那些对此应该没有先入为主的观念的人。这个问题既不简单也不愚蠢,我们至少可以将调查人员指向正确的方向。

不幸的是,我不知道有什么好的参考。 CLTL2稍微讨论了一下,但要了解它并不是很好。