當前位置:首頁 » 編程軟體 » 編譯法頒布時間

編譯法頒布時間

發布時間: 2022-06-10 08:12:02

『壹』 c語言創立時間

C語言是一門通用計算機編程語言,應用廣泛。C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。
盡管C語言提供了許多低級處理的功能,但仍然保持著良好跨平台的特性,以一個標准規格寫出的C語言程序可在許多電腦平台上進行編譯,甚至包含一些嵌入式處理器(單片機或稱MCU)以及超級電腦等作業平台。
二十世紀八十年代,為了避免各開發廠商用的C語言語法產生差異,由美國國家標准局為C語言制定了一套完整的美國國家標准語法,稱為ANSI C,作為C語言最初的標准。[1] 目前2011年12月8日,國際標准化組織(ISO)和國際電工委員會(IEC)發布的C11標準是C語言的第三個官方標准,也是C語言的最新標准,該標准更好的支持了漢字函數名和漢字標識符,一定程度上實現了漢字編程。

『貳』 了解什麼叫做jit compiling,與傳統的編譯技術有何不同

java 應用程序的性能經常成為開發社區中的討論熱點。因為該語言的設計初衷是使用解釋的方式支持應用程序的可移植性目標,早期
Java 運行時所提供的性能級別遠低於 C 和
C++
之類的編譯語言。盡管這些語言可以提供更高的性能,但是生成的代碼只能在有限的幾種系統上執行。在過去的十年中,Java
運行時供應商開發了一些復雜的動態編譯器,通常稱作即時(Just-in-time,JIT)編譯器。程序運行時,JIT
編譯器選擇將最頻繁執行的方法編譯成本地代碼。運行時才進行本地代碼編譯而不是在程序運行前進行編譯(用 C 或
C++ 編寫的程序正好屬於後一情形),保證了可移植性的需求。有些 JIT 編譯器甚至不使用解釋程序就能編譯所有的代碼,但是這些編譯器仍然通過在程序執行時進行一些操作來保持 Java 應用程序的可移植性。
由於動態編譯技術的多項改進,在很多應用程序中,現代的 JIT 編譯器可以產生與 C 或 C++
靜態編譯相當的應用程序性能。但是,仍然有很多軟體開發人員認為 —— 基於經驗或者傳聞 ——
動態編譯可能嚴重干擾程序操作,因為編譯器必須與應用程序共享 CPU。一些開發人員強烈呼籲對 Java
代碼進行靜態編譯,並且堅信那樣可以解決性能問題。對於某些應用程序和執行環境而言,這種觀點是正確的,靜態編譯可以極大地提高 Java
性能,或者說它是惟一的實用選擇。但是,靜態地編譯 Java 應用程序在獲得高性能的同時也帶來了很多復雜性。一般的
Java 開發人員可能並沒有充分地感受到 JIT 動態編譯器的優點。

本文考察了 Java 語言靜態編譯和動態編譯所涉及的一些問題,重點介紹了實時 (RT) 系統。簡要描述了 Java
語言解釋程序的操作原理並說明了現代 JIT 編譯器執行本地代碼編譯的優缺點。介紹了 IBM 在 WebSphere Real Time 中發布的
AOT 編譯技術和它的一些優缺點。然後比較了這兩種編譯策略並指出了幾種比較適合使用 AOT
編譯的應用程序領域和執行環境。要點在於這兩種編譯技術並不互斥:即使在使用這兩種技術最為有效的各種應用程序中,它們也分別存在一些影響應用程序的優缺
點。

執行 Java 程序

Java 程序最初是通過 Java SDK 的 javac程序編譯成本地的與平台無關的格式(類文件)。可將此格式看作 Java
平台,因為它定義了執行 Java 程序所需的所有信息。Java 程序執行引擎,也稱作 Java 運行時環境(JRE),包含了為特定的本地平台實現
Java 平台的虛擬機。例如,基於 linux 的 Intel x86 平台、Sun Solaris 平台和 AIX 操作系統上運行的 IBM
System p 平台,每個平台都擁有一個 JRE。這些 JRE 實現實現了所有的本地支持,從而可以正確執行為
Java 平台編寫的程序。

事實上,操作數堆棧的大小有實際限制,但是編程人員極少編寫超出該限制的方法。JVM 提供了安全性檢查,對那些創建出此類方法的編程人員進行通知。

Java 平台程序表示的一個重要部分是位元組碼序列,它描述了 Java
類中每個方法所執行的操作。位元組碼使用一個理論上無限大的操作數堆棧來描述計算。這個基於堆棧的程序表示提供了平台無關性,因為它不依賴任何特定本地平台
的 CPU 中可用寄存器的數目。可在操作數堆棧上執行的操作的定義都獨立於所有本地處理器的指令集。Java
虛擬機(JVM)規范定義了這些位元組碼的執行(參見 參考資料)。執行 Java 程序時,用於任何特定本地平台的任何 JRE 都必須遵守 JVM
規范中列出的規則。

因為基於堆棧的本地平台很少(Intel X87 浮點數協處理器是一個明顯的例外),所以大多數本地平台不能直接執行 Java 位元組碼。為了解決這個問題,早期的 JRE 通過解釋位元組碼來執行 Java 程序。即 JVM 在一個循環中重復操作:

◆獲取待執行的下一個位元組碼;

◆解碼;

◆從操作數堆棧獲取所需的操作數;

◆按照 JVM 規范執行操作;

◆將結果寫回堆棧。

這種方法的優點是其簡單性:JRE 開發人員只需編寫代碼來處理每種位元組碼即可。並且因為用於描述操作的位元組碼少於 255 個,所以實現的成本比較低。當然,缺點是性能:這是一個早期造成很多人對 Java 平台不滿的問題,盡管擁有很多其他優點。

解決與 C 或 C++ 之類的語言之間的性能差距意味著,使用不會犧牲可移植性的方式開發用於 Java 平台的本地代碼編譯。

編譯 Java 代碼

盡管傳聞中 Java 編程的 「一次編寫,隨處運行」
的口號可能並非在所有情況下都嚴格成立,但是對於大量的應用程序來說情況確實如此。另一方面,本地編譯本質上是特定於平台的。那麼 Java
平台如何在不犧牲平台無關性的情況下實現本地編譯的性能?答案就是使用 JIT 編譯器進行動態編譯,這種方法已經使用了十年(參見圖 1):

圖 1. JIT 編譯器

使用 JIT 編譯器時,Java
程序按每次編譯一個方法的形式進行編譯,因為它們在本地處理器指令中執行以獲得更高的性能。此過程將生成方法的一個內部表示,該表示與位元組碼不同但是其級
別要高於目標處理器的本地指令。(IBM JIT
編譯器使用一個表達式樹序列表示方法的操作。)編譯器執行一系列優化以提高質量和效率,最後執行一個代碼生成步驟將優化後的內部表示轉換成目標處理器的本
地指令。生成的代碼依賴運行時環境來執行一些活動,比如確保類型轉換的合法性或者對不能在代碼中直接執行的某些類型的對象進行分配。JIT
編譯器操作的編譯線程與應用程序線程是分開的,因此應用程序不需要等待編譯的執行。

圖 1 中還描述了用於觀察執行程序行為的分析框架,通過周期性地對線程取樣找出頻繁執行的方法。該框架還為專門進行分析的方法提供了工具,用來存儲程序的此次執行中可能不會改變的動態值。

因為這個 JIT 編譯過程在程序執行時發生,所以能夠保持平台無關性:發布的仍然是中立的 Java 平台代碼。C 和 C++ 之類的語言缺乏這種優點,因為它們在程序執行前進行本地編譯;發布給(本地平台)執行環境的是本地代碼。

挑戰

盡管通過 JIT 編譯保持了平台無關性,但是付出了一定代價。因為在程序執行時進行編譯,所以編譯代碼的時間將計入程序的執行時間。任何編寫過大型 C 或 C++ 程序的人都知道,編譯過程往往較慢。

為了克服這個缺點,現代的 JIT
編譯器使用了下面兩種方法的任意一種(某些情況下同時使用了這兩種方法)。第一種方法是:編譯所有的代碼,但是不執行任何耗時多的分析和轉換,因此可以快
速生成代碼。由於生成代碼的速度很快,因此盡管可以明顯觀察到編譯帶來的開銷,但是這很容易就被反復執行本地代碼所帶來的性能改善所掩蓋。第二種方法是:
將編譯資源只分配給少量的頻繁執行的方法(通常稱作熱方法)。低編譯開銷更容易被反復執行熱代碼帶來的性能優勢掩蓋。很多應用程序只執行少量的熱方法,因
此這種方法有效地實現了編譯性能成本的最小化。

動態編譯器的一個主要的復雜性在於權衡了解編譯代碼的預期獲益使方法的執行對整個程序的性能起多大作用。一個極端的例子是,程序執行後,您非常清楚哪些方
法對於這個特定的執行的性能貢獻最大,但是編譯這些方法毫無用處,因為程序已經完成。而在另一個極端,程序執行前無法得知哪些方法重要,但是每種方法的潛
在受益都最大化了。大多數動態編譯器的操作介於這兩個極端之間,方法是權衡了解方法預期獲益的重要程度。

Java 語言需要動態載入類這一事實對 Java
編譯器的設計有著重要的影響。如果待編譯代碼引用的其他類還沒有載入怎麼辦?比如一個方法需要讀取某個尚未載入的類的靜態欄位值。Java
語言要求第一次執行類引用時載入這個類並將其解析到當前的 JVM
中。直到第一次執行時才解析引用,這意味著沒有地址可供從中載入該靜態欄位。編譯器如何處理這種可能性?編譯器生成一些代碼,用於在沒有載入類時載入並解
析類。類一旦被解析,就會以一種線程安全的方式修改原始代碼位置以便直接訪問靜態欄位的地址,因為此時已獲知該地址。

IBM JIT
編譯器中進行了大量的努力以便使用安全而有效率的代碼補丁技術,因此在解析類之後,執行的本地代碼只載入欄位的值,就像編譯時已經解析了欄位一樣。另外一
種方法是生成一些代碼,用於在查明欄位的位置以前一直檢查是否已經解析欄位,然後載入該值。對於那些由未解析變成已解析並被頻繁訪問的欄位來說,這種簡單
的過程可能帶來嚴重的性能問題。

動態編譯的優點

動態地編譯 Java 程序有一些重要的優點,甚至能夠比靜態編譯語言更好地生成代碼,現代的 JIT 編譯器常常向生成的代碼中插入掛鉤以收集有關程序行為的信息,以便如果要選擇方法進行重編譯,就可以更好地優化動態行為。

關於此方法的一個很好的例子是收集一個特定 array操作的長度。如果發現每次執行操作時該長度基本不變,則可以為最頻繁使用的

array長度生成專門的代碼,或者可以調用調整為該長度的代碼序列。由於內存系統和指令集設計的特性,用於復制內存的最佳通用常式的執行速度通
常比用於復制特定長度的代碼慢。例如,復制 8
個位元組的對齊的數據可能需要一到兩條指令直接復制,相比之下,使用可以處理任意位元組數和任意對齊方式的一般復制循環可能需要 10 條指令來復制同樣的 8

個位元組。但是,即使此類專門的代碼是為某個特定的長度生成的,生成的代碼也必須正確地執行其他長度的復制。生成代碼只是為了使常見長度的操作執行得更快,
因此平均下來,性能得到了改進。此類優化對大多數靜態編譯語言通常不實用,因為所有可能的執行中長度恆定的操作比一個特定程序執行中長度恆定的操作要少得
多。

此類優化的另一個重要的例子是基於類層次結構的優化。例如,一個虛方法調用需要查看接收方對象的類調用,以便找出哪個實際目標實現了接收方對象的虛方法。
研究表明:大多數虛調用只有一個目標對應於所有的接收方對象,而 JIT
編譯器可以為直接調用生成比虛調用更有效率的代碼。通過分析代碼編譯後類層次結構的狀態,JIT
編譯器可以為虛調用找到一個目標方法,並且生成直接調用目標方法的代碼而不是執行較慢的虛調用。當然,如果類層次結構發生變化,並且出現另外的目標方法,
則 JIT
編譯器可以更正最初生成的代碼以便執行虛調用。在實踐中,很少需要作出這些更正。另外,由於可能需要作出此類更正,因此靜態地執行這種優化非常麻煩。

因為動態編譯器通常只是集中編譯少量的熱方法,所以可以執行更主動的分析來生成更好的代碼,使編譯的回報更高。事實上,大部分現代的
JIT
編譯器也支持重編譯被認為是熱方法的方法。可以使用靜態編譯器(不太強調編譯時間)中常見的非常主動的優化來分析和轉換這些頻繁執行的方法,以便生成更好
的代碼並獲得更高的性能。

這些改進及其他一些類似的改進所產生的綜合效果是:對於大量的 Java 應用程序來說,動態編譯已經彌補了與 C 和 C++ 之類語言的靜態本地編譯性能之間的差距,在某些情況下,甚至超過了後者的性能。

缺點

但是,動態編譯確實具有一些缺點,這些缺點使它在某些情況下算不上一個理想的解決方案。例如,因為識別頻繁執行的方法以及編譯這些方法需要時間,所以應用
程序通常要經歷一個准備過程,在這個過程中性能無法達到其最高值。在這個准備過程中出現性能問題有幾個原因。首先,大量的初始編譯可能直接影響應用程序的
啟動時間。不僅這些編譯延遲了應用程序達到穩定狀態的時間(想像 Web
伺服器經
歷一個初始階段後才能夠執行實際有用的工作),而且在准備階段中頻繁執行的方法可能對應用程序的穩定狀態的性能所起的作用也不大。如果 JIT
編譯會延遲啟動又不能顯著改善應用程序的長期性能,則執行這種編譯就非常浪費。雖然所有的現代 JVM
都執行調優來減輕啟動延遲,但是並非在所有情況下都能夠完全解決這個問題。

其次,有些應用程序完全不能忍受動態編譯帶來的延遲。如 GUI 介面之類互動式應用程序就是這樣的例子。在這種情況下,編譯活動可能對用戶使用造成不利影響,同時又不能顯著地改善應用程序的性能。

最後,用於實時環境並具有嚴格的任務時限的應用程序可能無法忍受編譯的不確定性性能影響或動態編譯器本身的內存開銷。

因此,雖然 JIT 編譯技術已經能夠提供與靜態語言性能相當(甚至更好)的性能水平,但是動態編譯並不適合於某些應用程序。在這些情況下,Java 代碼的提前(Ahead-of-time,AOT)編譯可能是合適的解決方案。

AOT Java 編譯

大致說來,Java 語言本地編譯應該是為傳統語言(如 C++ 或
Fortran)而開發的編譯技術的一個簡單應用。不幸的是,Java 語言本身的動態特性帶來了額外的復雜性,影響了 Java
程序靜態編譯代碼的質量。但是基本思想仍然是相同的:在程序執行前生成 Java 方法的本地代碼,以便在程序運行時直接使用本地代碼。目的在於避免
JIT 編譯器的運行時性能消耗或內存消耗,或者避免解釋程序的早期性能開銷。

挑戰

動態類載入是動態 JIT 編譯器面臨的一個挑戰,也是 AOT
編譯的一個更重要的問題。只有在執行代碼引用類的時候才載入該類。因為是在程序執行前進行 AOT
編譯的,所以編譯器無法預測載入了哪些類。就是說編譯器無法獲知任何靜態欄位的地址、任何對象的任何實例欄位的偏移量或任何調用的實際目標,甚至對直接調
用(非虛調用)也是如此。在執行代碼時,如果證明對任何這類信息的預測是錯誤的,這意味著代碼是錯誤的並且還犧牲了 Java 的一致性。

因為代碼可以在任何環境中執行,所以類文件可能與代碼編譯時不同。例如,一個 JVM
實例可能從磁碟的某個特定位置載入類,而後面一個實例可能從不同的位置甚至網路載入該類。設想一個正在進行 bug
修復的開發環境:類文件的內容可能隨不同的應用程序的執行而變化。此外,Java 代碼可能在程序執行前根本不存在:比如 Java
反射服務通常在運行時生成新類來支持程序的行為。

缺少關於靜態、欄位、類和方法的信息意味著嚴重限制了 Java 編譯器中優化框架的大部分功能。內聯可能是靜態或動態編譯器應用的最重要的優化,但是由於編譯器無法獲知調用的目標方法,因此無法再使用這種優化。

內聯

內聯是一種用於在運行時生成代碼避免程序開始和結束時開銷的技術,方法是將函數的調用代碼插入到調用方的函數中。但是內聯最大的益處可能是優化方可見的代碼的范圍擴大了,從而能夠生成更高質量的代碼。下面是一個內聯前的代碼示例:

int foo() { int x=2, y=3; return bar(x,y); }final int bar(int a, int b) { return a+b; }

如果編譯器可以證明這個 bar就是 foo()中調用的那個方法,則 bar中的代碼可以取代 foo()中對
bar()的調用。這時,bar()方法是 final類型,因此肯定是 foo()中調用的那個方法。甚至在一些虛調用例子中,動態 JIT
編譯器通常能夠推測性地內聯目標方法的代碼,並且在絕大多數情況下能夠正確使用。編譯器將生成以下代碼:

int foo() { int x=2, y=3; return x+y; }

在這個例子中,簡化前名為值傳播的優化可以生成直接返回
5的代碼。如果不使用內聯,則不能執行這種優化,產生的性能就會低很多。如果沒有解析
bar()方法(例如靜態編譯),則不能執行這種優化,而代碼必須執行虛調用。運行時,實際調用的可能是另外一個執行兩個數字相乘而不是相加的
bar方法。所以不能在 Java 程序的靜態編譯期間直接使用內聯。

AOT
代碼因此必須在沒有解析每個靜態、欄位、類和方法引用的情況下生成。執行時,每個這些引用必須利用當前運行時環境的正確值進行更新。這個過程可能直接影響
第一次執行的性能,因為在第一次執行時將解析所有引用。當然,後續執行將從修補代碼中獲益,從而可以更直接地引用實例、靜態欄位或方法目標。

另外,為 Java 方法生成的本地代碼通常需要使用僅在單個 JVM 實例中使用的值。例如,代碼必須調用 JVM
運行時中的某些運行時常式來執行特定操作,如查找未解析的方法或分配內存。這些運行時常式的地址可能在每次將 JVM 載入到內存時變化。因此 AOT
編譯代碼需要綁定到 JVM 的當前執行環境中,然後才能執行。其他的例子有字元串的地址和常量池入口的內部位置。

在 WebSphere Real Time 中,AOT 本地代碼編譯通過 jxeinajar工具(參見圖 2)來執行。該工具對 JAR 文件中所有類的所有方法應用本地代碼編譯,也可以選擇性地對需要的方法應用本地代碼編譯。結果被存儲到名為 Java eXEcutable (JXE) 的內部格式中,但是也可輕松地存儲到任意的持久性容器中。

您可能認為對所有的代碼進行靜態編譯是最好的方法,因為可以在運行時執行最大數量的本地代碼。但是此處可以作出一些權衡。編譯的方法越多,代碼佔用的內存
就越多。編譯後的本地代碼大概比位元組碼大 10 倍:本地代碼本身的密度比位元組碼小,而且必須包含代碼的附加元數據,以便將代碼綁定到 JVM
中,並且在出現異常或請求堆棧跟蹤時正確執行代碼。構成普通 Java 應用程序的 JAR
文件通常包含許多很少執行的方法。編譯這些方法會消耗內存卻沒有什麼預期收益。相關的內存消耗包括以下過程:將代碼存儲到磁碟上、從磁碟取出代碼並裝入
JVM,以及將代碼綁定到 JVM。除非多次執行代碼,否則這些代價不能由本地代碼相對解釋的性能優勢來彌補。

圖 2. jxeinajar

跟大小問題相違背的一個事實是:在編譯過的方法和解釋過的方法之間進行的調用(即編譯過的方法調用解釋過的方法,或者相反)可能比這兩類方法各自內部之間
進行的調用所需的開銷大。動態編譯器通過最終編譯所有由 JIT
編譯代碼頻繁調用的那些解釋過的方法來減少這項開銷,但是如果不使用動態編譯器,則這項開銷就不可避免。因此如果是選擇性地編譯方法,則必須謹慎操作以使
從已編譯方法到未編譯方法的轉換最小化。為了在所有可能的執行中都避免這個問題而選擇正確的方法會非常困難。
優點
雖然 AOT 編譯代碼具有上述的缺點和挑戰,但是提前編譯 Java 程序可以提高性能,尤其是在不能將動態編譯器作為有效解決方案的環境中。

可以通過謹慎地使用 AOT 編譯代碼加快應用程序啟動,因為雖然這種代碼通常比 JIT
編譯代碼慢,但是卻比解釋代碼快很多倍。此外,因為載入和綁定 AOT
編譯代碼的時間通常比檢測和動態編譯一個重要方法的時間少,所以能夠在程序執行的早期達到那樣的性能。類似地,互動式應用程序可以很快地從本地代碼中獲
益,無需使用引起較差響應能力的動態編譯。

RT 應用程序也能從 AOT 編譯代碼中獲得重要的收益:更具確定性的性能超過了解釋的性能。WebSphere Real Time
使用的動態 JIT 編譯器針對在 RT 系統中的使用進行了專門的調整。使編譯線程以低於 RT
任務的優先順序操作,並且作出了調整以避免生成帶有嚴重的不確定性性能影響的代碼。但是,在一些 RT 環境中,出現 JIT
編譯器是不可接受的。此類環境通常需要最嚴格的時限管理控制。在這些例子中,AOT
編譯代碼可以提供比解釋過的代碼更好的原始性能,又不會影響現有的確定性。消除 JIT
編譯線程甚至消除了啟動更高優先順序 RT 任務時發生的線程搶占所帶來的性能影響。

優缺點統計

動態(JIT)編譯器支持平台中立性,並通過利用應用程序執行的動態行為和關於載入的類及其層次結構的信息來生成高質量的代碼。但是
JIT
編譯器具有一個有限的編譯時預算,而且會影響程序的運行時性能。另一方面,靜態(AOT)編譯器則犧牲了平台無關性和代碼質量,因為它們不能利用程序的動
態行為,也不具有關於載入的類或類層次結構的信息。AOT 編譯擁有有效無限制的編譯時預算,因為 AOT
編譯時間不會影響運行時性能,但是在實踐中開發人員不會長期等待靜態編譯步驟的完成。

表 1 總結了本文討論的 Java 語言動態和靜態編譯器的一些特性:

表 1. 比較編譯技術

兩種技術都需要謹慎選擇編譯的方法以實現最高的性能。對動態編譯器而言,編譯器自身作出決策,而對於靜態編譯器,由開發人員作出選擇。讓
JIT 編譯器選擇編譯的方法是不是優點很難說,取決於編譯器在給定情形中推斷能力的好壞。在大多數情況下,我們認為這是一種優點。

因為它們可以最好地優化運行中的程序,所以 JIT 編譯器在提供穩定狀態性能方面更勝一籌,而這一點在大量的生產 Java
系統中最為重要。靜態編譯可以產生最佳的互動式性能,因為沒有運行時編譯行為來影響用戶預期的響應時間。通過調整動態編譯器可以在某種程度上解決啟動和確
定性性能問題,但是靜態編譯在需要時可提供最快的啟動速度和最高級別的確定性。表 2 在四種不同的執行環境中對這兩種編譯技術進行了比較:

表 2. 使用這些技術的最佳環境

圖 3 展示了啟動性能和穩定狀態性能的總體趨勢:

圖 3. AOT 和 JIT 的性能對比

使用 JIT 編譯器的初始階段性能很低,因為要首先解釋方法。隨著編譯方法的增多及 JIT
執行編譯所需時間的縮短,性能曲線逐漸升高最後達到性能峰值。另一方面,AOT 編譯代碼啟動時的性能比解釋的性能高很多,但是無法達到 JIT
編譯器所能達到的最高性能。將靜態代碼綁定到 JVM 實例中會產生一些開銷,因此開始時的性能比穩定狀態的性能值低,但是能夠比使用 JIT
編譯器更快地達到穩定狀態的性能水平。

沒有一種本地代碼編譯技術能夠適合所有的 Java
執行環境。某種技術所擅長的通常正是其他技術的弱項。出於這個原因,需要同時使用這兩種編譯技術以滿足 Java
應用程序開發人員的要求。事實上,可以結合使用靜態和動態編譯以便提供最大可能的性能提升 —— 但是必須具備平台無關性,它是 Java
語言的主要賣點,因此不成問題。

結束語

本文探討了 Java 語言本地代碼編譯的問題,主要介紹了 JIT 編譯器形式的動態編譯和靜態 AOT 編譯,比較了二者的優缺點。

雖然動態編譯器在過去的十年裡實現了極大的成熟,使大量的各種 Java 應用程序可以趕上或超過靜態編譯語言(如 C++ 或
Fortran)所能夠達到的性能。但是動態編譯在某些類型的應用程序和執行環境中仍然不太合適。雖然 AOT
編譯號稱動態編譯缺點的萬能解決方案,但是由於 Java 語言本身的動態特性,它也面臨著提供本地編譯全部潛能的挑戰。

這兩種技術都不能解決 Java 執行環境中本地代碼編譯的所有需求,但是反過來又可以在最有效的地方作為工具使用。這兩種技術可以相互補充。能夠恰當地使用這兩種編譯模型的運行時系統可以使很大范圍內的應用程序開發環境中的開發人員和用戶受益。

『叄』 JAVA語言是什麼時候誕生的誰有詳細資料

JAVA語言是1995年誕生。

任職於太陽微系統(Sun Microsystems)的詹姆斯·高斯林等人於1990年代初開發Java語言的雛形,最初被命名為Oak,目標設置在家用電器等小型系統的編程語言,應用在電視機、電話、鬧鍾、烤麵包機等家用電器的控制和通信。

由於這些智能化家電的市場需求沒有預期的高,Sun公司放棄了該項計劃。隨著1990年代互聯網的發展,Sun公司看見Oak在互聯網上應用的前景,於是改造了Oak,於1995年5月以Java的名稱正式發布。Java伴隨著互聯網的迅猛發展而發展,逐漸成為重要的網路編程語言。

(3)編譯法頒布時間擴展閱讀

特點

1、Java看起來設計得很像C++,但是為了使語言小和容易熟悉,設計者們把C++語言中許多可用的特徵去掉了,這些特徵是一般程序員很少使用的。

2、Java設計成支持在網路上應用,它是分布式語言。Java既支持各種層次的網路連接,又以Socket類支持可靠的流網路連接,所以用戶可以產生分布式的客戶機和伺服器。

3、Java編譯程序生成位元組碼(byte-code),而不是通常的機器碼。Java位元組碼提供對體系結構中性的目標文件格式,代碼設計成可有效地傳送程序到多個平台。

『肆』 請問,編譯軟體最早是由誰發明出來的

Grave of Grace

後記

Grace Hopper是個非常amazing的人 (常被稱為Amazing Grace),崇拜她的人相當多。雖然她的事跡很多,但是還有很多有類似事跡的人並沒有像她這樣受到眾人的崇拜。由其中一點我們可以看出來:從1947年開始 (二戰結束後第二年),她獲得了第一個榮譽博士學位 (賓州大學),從那以後,她先後被40多所大學授予榮譽博士學位,其中包括芝加哥大學、華盛頓大學、馬里蘭大學等知名學府。各種婦女社會團體和學術組織都曾授予Grace各種稱號和獎勵。1991年,布希總統在白宮授予她的「美國國家技術獎」 (National Medal of Technology) 是其中的最高獎項,她也是至今惟一獲此殊榮的美國女性。她的名言有很多,她自己最喜歡的,也是她最喜歡對所謂的「年輕人」說的 (在她年老時,她所謂的年輕人就是「年齡不到我的一半的人就叫做年輕人」),這句話是:

「A ship in port is safe, but that is not what ships are built for.」

語錄

下面Grace的語錄中有幾句比較有意思的話。

  • From then on, when anything went wrong with a computer, we said it had bugs in it.

  • The most dangerous phrase in the language is, 「We』ve always done it this way.」

  • Humans are allergic to change. They love to say, 「We』ve always done it this way.」 I try to fight that. That』s why I have a clock on my wall that runs counter-clockwise.

  • Leadership is a two-way street, loyalty up and loyalty down. Respect for one』s superiors; care for one』s crew.

  • One accurate measurement is worth a thousand expert opinions.

  • Someday, on the corporate balance sheet, there will be an entry which reads, 「Information」; For in most cases, the information is more valuable than the hardware which processes it.

  • We』re flooding people with information. We need to feed it through a processor. A human must turn information into intelligence or knowledge. We』ve tended to forget that no computer will ever ask a new question.

  • To me programming is more than an important practical art. It is also a gigantic undertaking in the foundations of knowledge.

  • They told me computers could only do arithmetic.

  • In pioneer days they used oxen for heavy pulling, and when one ox couldn』t budge a log, they didn』t try to grow a larger ox. We shouldn』t be trying for bigger computers, but for more systems of computers.

  • Life was simple before World War II. After that, we had systems.

  • We went overboard on management and forgot about leadership. It might help if we ran the MBAs out of Washington.

  • At any given moment, there is always a line representing what your boss will believe. If you step over it, you will not get your budget. Go as close to that line as you can.

  • I seem to do a lot of retiring.

  • I handed my passport to the immigration officer, and he looked at it and looked at me and said, 「What are you?」

  • 參考

    維基網路:
    http://en.wikipedia.org/wiki/Grace_Hopper

    國立中央大學數學系:
    http://li.math.ncu.e.tw/bcc16/pool/3.06.shtml

    耶魯大學計算機系:
    http://cs-www.cs.yale.e/homes/tap/Files/hopper-story.html

    計算機先驅:
    http://202.207.0.245:9001/jisuanjifazhanshi/xianqu/18.htm

    This entry was posted in網路3Cand taggedcompiler,debug,Grace Murray Hopper,傳記,發明,編譯器,起源. Bookmark thepermalink.Post a commentor leave a trackback:Trackback URL.

『伍』 vivo手機的編譯日期是什麼意思

vivo手機編譯時間是手機系統軟體版本編譯完成的時間,新手機的系統編譯時間通常會早於手機出廠和購買時間的。

  • 補充說明:

查看編譯日期方法:進入手機設置-更多設置-關於手機中查看編譯時間。

  • 具體操作步驟:

1、待機桌面進入設置

註:系統的編譯的時間不可以更改

『陸』 簡述計算機程序設計語言的發展歷程。

在過去的幾十年間,大量的程序設計語言被發明、被取代、被修改或組合在一起。盡管人們多次試圖創造一種通用的程序設計語言,卻沒有一次嘗試是成功的。

之所以有那麼多種不同的編程語言存在的原因是,編寫程序的初衷其實也各不相同;新手與老手之間技術的差距非常大,而有許多語言並對新手來說太難學;還有,不同程序之間的運行成本各不相同。

有許多用於特殊用途的語言,只在特殊情況下使用。例如,PHP專門用來顯示網頁;Perl更適合文本處理;C語言被廣泛用於操作系統和編譯器的開發。

高級程序設計語言的出現使得計算機程序設計語言不再過度地依賴某種特定的機器或環境。這是因為高級語言在不同的平台上會被編譯成不同的機器語言,而不是直接被機器執行。最早出現的編程語言之一FORTRAN的一個主要目標,就是實現平台獨立。



(6)編譯法頒布時間擴展閱讀:

如果所使用的翻譯的機制是將所要翻譯的程序代碼作為一個整體翻譯,並之後運行內部格式,那麼這個翻譯過程就稱為編譯。

因此,一個編譯器是一個將可閱讀的程序文本作為輸入的數據,然後輸出可執行文件。所輸出的可執行文件可以是機器語言,由計算機的中央處理器直接運行,或者是某種模擬器的二進制代碼。

如果程序代碼是在運行時才即時翻譯,那麼這種翻譯機制就被稱作解譯。經解譯的程序運行速度往往比編譯的程序慢,但往往更具靈活性,因為它們能夠與執行環境互相作用。

『柒』 c語言什麼時候誕生

1969-1973年在美國電話電報公司(AT&T)貝爾實驗室開始了C語言的最初研發。根據C語言的發明者丹尼斯·里奇 (Dennis Ritchie) 說,C 語言最重要的研發時期是在1972年。
C語言之所以命名為C,是因為C語言源自Ken Thompson發明的 B語言,而B語言則源自BCPL語言。
C語言的誕生是和UNIX操作系統的開發密不可分的,原先的UNIX操作系統都是用匯編語言寫的,1973年UNIX操作系統的核心用C語言改寫,從此以後,C語言成為編寫操作系統的主要語言。

『捌』 什麼是編譯原理

編譯原理是計算機專業的一門重要專業課,旨在介紹編譯程序構造的一般原理和基本方法。內容包括語言和文法、詞法分析、語法分析、語法制導翻譯、中間代碼生成、存儲管理、代碼優化和目標代碼生成。 編譯原理是計算機專業設置的一門重要的專業課程。雖然只有少數人從事編譯方面的工作,但是這門課在理論、技術、方法上都對學生提供了系統而有效的訓練,有利於提高軟體人員的素質和能力。
這門課程關注的是編譯器方面的產生原理和技術問題,似乎和計算機的基礎領域不沾邊,可是編譯原理卻一直作為大學本科的 必修課程,同時也成為了研究生入學考試的必考內容。編譯原理及技術從本質上來講就是一個演算法問題而已,當然由於這個問題十分復雜,其解決演算法也相對復雜。 我們學的數據結構與演算法分析也是講演算法的,不過講的基礎演算法,換句話說講的是演算法導論,而編譯原理這門課程講的就是比較專註解決一種的演算法了。在20世紀 50年代,編譯器的編寫一直被認為是十分困難的事情,第一Fortran的編譯器據說花了18年的時間才完成。在人們嘗試編寫編譯器的同時,誕生了許多跟 編譯相關的理論和技術,而這些理論和技術比一個實際的編譯器本身價值更大。就猶如數學家們在解決著名的哥德巴赫猜想一樣,雖然沒有最終解決問題,但是其間 誕生不少名著的相關數論。

『玖』 什麼是編譯時間

用戶使用編譯程序對其個人編制的源程序進行編譯的過程稱為程序編譯。編譯時間(compiling time) 指編譯程序將源程序編譯成目標程序所佔用的時間。

1 如何減少編譯時間
一是執行每日自動構建。每日自動構建的原理很簡單:安裝每日構建工具CCNET(不熟悉該工具的同學可以去搜索下)。然後在源碼伺服器上安裝編譯環境。源碼伺服器每天獲取最新代碼,每天下班後開始編譯最新代碼,經過一個晚上基本上就能把庫和應用程序都編好,到了第二天開發人員只需下載最新的庫文件和代碼文件而不須自己重新編譯。這樣就能大大節省時間了。
二是使用聯合編譯器IncrediBuild。這個工具估計大家都不陌生。最近試驗了一個新想法,寫一個批處理文件,將SVN和IncrediBuild綁在一起,實現了從源碼更新到工程編譯。


2 批處理文件的命令語法
svnupinclude//更新伺服器的include文件夾到本地
BuildConsoleD:\Code\MySolution.sln/prj="MyApp"/build/OpenMonitor/cfg="Debug|Win32"
BuildConsole是IncrediBuild的命令行工具,
D:\Code\MySolution.sln是你的解決方案文件絕對路徑,
/prj參數設置你要編譯的工程,如果你要編譯多個工程,可以這樣設置,/prj="prj1,prj2,prj3",
/prj參數也支持通配符,/prj="*"即為編譯MySolution.sln下的所有工程
/build為編譯工程,若改為/rebuild即是清理重編工程。
/OpenMonitor為打開IncrediBuild的圖形化界面,去掉該參數則不出現圖形界面。
/cfg為編譯設置選項,如要編release版本,可以改為Release|Win32。
把上面的代碼保存為BuildDebug.bat,把文件保存在D:\Code\路徑下(即源碼根目錄,下面有include、src和vs三個文件夾),然後運行這個批處理文件就相當於把從更新源碼到編譯源碼這一系列動作都執行了。

『拾』 c語言編程

C語言基礎教程別看了,學習C語言不能脫離具體的系統,不能不了解計算機體系結構和操作系統原理、編譯原理,推薦你看這本開源的書:
《Linux C編程一站式學習》
http://learn.akae.cn/media/index.html
如果是在Windows上學習,可以安裝cygwin來模擬linux環境,下載地址:
http://cygwin.cn/site/install/

下面貼一下這本書的介紹,磨刀不誤砍柴工,看過之後你就會愛上這本書了:

這本書有什麼特點?面向什麼樣的讀者?

這本書最初是為北京亞嵌教育研究中心的嵌入式Linux系統工程師就業班課程量身定做的教材之一。該課程是為期四個月的全日制職業培訓,要求學員畢業時具備非常Solid的C編程能力,能熟練地使用Linux系統,同時對計算機體系結構與指令集、操作系統原理和設備驅動程序都有較深入的了解。然而學員入學時的水平是非常初級而且參差不齊的:學歷有專科、本科也有研究生,專業有和計算機相關的也有很不相關的(例如會計專業),以前從事的職業有和技術相關的也有完全不相關的(例如HR),年齡從二十齣頭到三十五六歲的都有。這么多背景完全不同、基礎完全不同、思維習慣和理解能力完全不同的人來聽同一堂課,大家都迫切希望學會嵌入式開發技術,投身IT行業,這就是職業教育的特點,也是我編這本書時需要考慮的主要問題。

學習編程絕不是一件簡單的事,尤其是對於零基礎的初學者來說。大學的計算機專業有四年時間從零基礎開始培養一個人,微積分、線代、隨機、離散、組合、自動機、編譯原理、操作系統、計算機組成原理等等一堆基礎課,再加上C/C++、Java、資料庫、網路、軟體工程、計算機圖形學等等一堆專業課,最後培養出一個能找到工作的學生。很遺憾這最後一條很多學校沒有做好,來亞嵌培訓的很多學生就是四年這么學過來的,但據我們考查他們的基礎幾乎為零,我不知道為什麼。與之形成鮮明對比的是,只給我們四個月的時間,同樣要求從零基礎開始,最後培養出一個能找到工作的學生,而且還要保證他找到工作,這就是職業教育的特點。

為什麼我說「只給我們四個月的時間」?我們倒是想教四年呢,但學時的長短我們做不了主,是由市場規律決定的。四年的任務要求四個月做好,要怎麼完成這樣一個幾乎不可能的任務?有些職業教育給出的答案是「實用主義」,打出了「有用就學,沒有用就不學」的口號,大肆貶低說大學里教的基礎課都是過時的、無用的,只有他們教的技術才是實用的,這種炒作很不好,我認為大學里教的每一門課都是非常有用的,基礎知識在任何時候都不會過時,倒是那些時髦的「實用技術」有可能很快就過時了。

四年的任務怎麼才能用四個月做好?我們給出的答案是「優化」。現在大學里安排的課程體系最大的缺點就是根本不考慮優化。每個過來人都會有這樣的感覺:大一大二學了好多數學課,卻不知道都是干什麼用的,為什麼要學。連它有什麼用都不知道怎麼能有興趣學好呢?然後到大三大四學專業課時,用到以前的知識了,才發現以前學的數學是多麼有用,然而早就忘得一干二凈了,考完試都還給老師了,回頭重新學吧,這時候才發現很多東西以前根本沒學明白,現在才真的學明白了,那麼前兩年的時間豈不是都浪費了?大學里的課程體系還有一個缺點就是不靈活,每門課必須佔一個學期,必須由一個老師教,不同課程的老師之間沒有任何溝通和銜接,其實這些課程之間是相互依賴的,把它們強行拆開是不符合人的認知規律的。比如我剛上大學的時候,大一上半學期就被逼著學C語言,其實C語言是一門很難的編程語言,不懂編譯原理、操作系統和計算機體系結構根本不可能學明白,那半個學期自然就浪費掉了。當時幾乎所有學校的計算機相關專業都是這樣,大一上來就學C語言,有的學校更瘋狂,上來就學C++,導致大多數學生都以為自己會C語言,但其實都是半吊子水平,到真正寫代碼的時候經常為一個Bug搞得焦頭爛額,卻沒有機會再系統地學一遍C語言,因為在學校看來,C語言課早在大一就給你「上完了」,就像一頓飯已經吃完了,不管你吃飽沒吃飽,不會再讓你重吃一遍了。顯而易見,如果要認真地對這些課程做優化,的確是有很多水份可以擠的。

本書有以下特點:

*

不是孤立地講C語言,而是和編譯原理、操作系統、計算機體系結構結合起來講。或者說,本書的內容只是以C語言為載體,真正講的是計算機的原理和程序的原理。
*

強調基本概念和基本原理,在編排順序上非常重視概念之間的依賴關系,每次引入一個新的概念,只依賴於前面章節已經講過的概念,而絕不會依賴後面章節要講的概念。有些地方為了敘述得完整,也會引用後面要講的內容,比如說「有關XX我們到XX章再仔細講解」,凡是這種引用都不是必要的依賴,可以當它不存在,只管繼續往下看就行了。
*

盡量做到每個知識點直到要用的時候才引入。過早引入一個知識點,講完了又不用它,讀者很快就會遺忘,這是不符合認知規律的。

這是一本從零基礎開始學習編程的書,不要求讀者有任何編程經驗,但讀者至少需要具備以下素質:

*

熟悉Linux系統的基本操作。如果不具備這一點,請先參考其它教材學習Linux系統的基本操作,熟練之後再學習本書,《鳥哥的Linux私房菜》據說是 Linux系統管理和應用方面比較好的一本書。但學習本書並不需要會很多系統管理技術,只要會用基本命令,會自己安裝系統和軟體包就足夠了。
*

具有高中畢業的數學水平。本書會用到高中的數學知識,事實上,如果不具有高中畢業的數學水平,也不必考慮做程序員了。但並不是說只要具有高中畢業的數學水平就足夠做程序員了,只能說看這本書應該沒有問題,數學是程序員最重要的修養,計算機科學其實就是數學的一個分支,如果你的數學功底很差,日後還需惡補一下。
*

具有高中畢業的英文水平。理由同上。
*

對計算機的原理和本質深感興趣,不是為就業而學習,不是為拿高薪而學習,而是真的感興趣,想把一切來龍去脈搞得清清楚楚而學習。
*

勤於思考。本書盡最大努力理清概念之間的依賴關系,力求一站式學習,讀者不需要為了找一個概念的定義去翻其它書,也不需要為了搞清楚一個概念在本書中前後一通亂翻,只需從前到後按順序學習即可。但一站式學習並不等於傻瓜式學習,有些章節有一定的難度,需要積極思考才能領會。本書可以替你節省時間,但不能替你思考,不要指望像看小說一樣走馬觀花看一遍就能學會。

又是一本C語言書。好吧,為什麼我要學這本書而不是譚浩強或者K&R? 請點評

譚浩強的書我就不說什麼了。居然教學生include一個.c文件。

K&R 是公認的世界上最經典的C語言教程,這點毫無疑問。在C標准出台之前,K&R第一版就是事實上的C標准。C89標准出台之後,K&R跟著標准推出了第二版,可惜此後就沒有更新過了,所以不能反映C89之後C語言的發展以及最新的C99標准,本書在這方面做了很多補充。上面我說過了,這本書與其說是講C語言,不如說是以C語言為載體講計算機和操作系統的原理,而K&R就是為了講C語言而講C語言,側重點不同,內容編排也很不相同。 K&R寫得非常好,代碼和語言都非常簡潔,但很可惜,只有會C語言的人才懂得欣賞它,K&R是非常不適合入門學習的,尤其不適合零基礎的學生入門學習。
這本書「是什麼」和「不是什麼」 請點評

本書包括三大部分:

*

C語言入門。介紹基本的C語法,幫助沒有任何編程經驗的讀者理解什麼是程序,怎麼寫程序,培養程序員的思維習慣,找到編程的感覺。前半部分改編自[ThinkCpp]。
*

C語言本質。結合計算機和操作系統的原理講解C程序是怎麼編譯、鏈接、運行的,同時全面介紹C的語法。位運算的章節改編自亞嵌教育林小竹老師的講義,鏈表和二叉樹的章節改編自亞嵌教育朱老師的講義。匯編語言的章節改編自[GroudUp],在該書的最後一章提到,學習編程有兩種Approach,一種是Bottom Up,一種是Top Down,各有優缺點,需要兩者結合起來。所以我編這本書的思路是,第一部分Top Down,第二部分Bottom Up,第三部分可以算填了中間的空隙,三部分全都圍繞C語言展開。
*

Linux系統編程。介紹各種Linux系統函數和內核的工作原理。Socket編程的章節改編自亞嵌教育衛劍釩老師的講義。

這本書定位在入門級,雖然內容很多,但不是一本網路全書,除了C語言基本要講透之外其它內容都不深入,書中列出了很多參考資料,是讀者進一步學習的起點。 K&R的第一章是一個Whirlwind Tour,把全書的內容簡單過了一遍,然後再逐個深入進去講解。本書也可以看作是計算機專業課程體系的一個Whirlwind Tour,學習完本書之後有了一個全局觀,再去學習那些參考資料就應該很容易上手了。
為什麼要在Linux平台上學C語言?用Windows學C語言不好嗎? 請點評

用 Windows還真的是學不好C語言。C語言是一種面向底層的編程語言,要寫好C程序,必須對操作系統的工作原理非常清楚,因為操作系統也是用C寫的,我們用C寫應用程序直接使用操作系統提供的介面。既然你選擇了看這本書,你一定了解:Linux是一種開源的操作系統,你有任何疑問都可以從源代碼和文檔中找到答案,即使你看不懂源代碼,也找不到文檔,也很容易找個高手教你,各種郵件列表、新聞組和論壇上從來都不缺樂於助人的高手;而Windows是一種封閉的操作系統,除了微軟的員工別人都看不到它的源代碼,只能通過文檔去猜測它的工作原理,更糟糕的是,微軟向來喜歡藏著揶著,好用的功能留著自己用,而不會寫到文檔里公開。本書的第一部分在Linux或Windows平台上學習都可以,但第二部分和第三部分介紹了很多Linux操作系統的原理以幫助讀者更深入地理解C語言,只能在Linux平台上學習。

Windows平台上的開發工具往往和各種集成開發環境(IDE,Integrated Development Environment)綁在一起,例如Visual Studio、Eclipse等。使用IDE確實很便捷,但IDE對於初學者絕對不是好東西。微軟喜歡宣揚傻瓜式編程的理念,告訴你用滑鼠拖幾個控制項,然後點一個按鈕就可以編譯出程序來,但是真正有用的程序有哪個是這么拖出來的?很多從Windows平台入門學編程的人,編了好幾年程序,還是只知道編完程序點一個按鈕就可以跑了,把幾個源文件拖到一個項目里就可以編譯到一起了,如果有更復雜的需求他們就傻眼了,因為他們腦子里只有按鈕、菜單的概念,根本沒有編譯器、鏈接器、Makefile的概念,甚至連命令行都沒用過,然而這些都是初學編程就應該建立起來的基本概念。另一方面,編譯器、鏈接器和C語言的語法有密切的關系,不了解編譯器、鏈接器的工作原理,也不可能真正掌握C的語法。所以,IDE並沒有幫助你學習,而是阻礙了你學習,本來要學好C編程只要把語法和編譯命令學會就行了,現在有了IDE,除了學會語法和編譯命令,你還得弄清楚編譯命令和IDE是怎麼集成的,這才算學明白了,本來就很復雜的學習任務被IDE搞得更加復雜了。Linux用戶的使用習慣從來都是以敲命令為主,以滑鼠操作為輔,從學編程的第一天起就要敲命令編譯程序,等到你把這些基本概念都搞清楚了,你覺得哪個IDE好用你再去用,不過到那時候你可能會更喜歡vi或emacs而不是IDE了。

熱點內容
內置存儲卡可以拆嗎 發布:2025-05-18 04:16:35 瀏覽:336
編譯原理課時設置 發布:2025-05-18 04:13:28 瀏覽:378
linux中進入ip地址伺服器 發布:2025-05-18 04:11:21 瀏覽:612
java用什麼軟體寫 發布:2025-05-18 03:56:19 瀏覽:32
linux配置vim編譯c 發布:2025-05-18 03:55:07 瀏覽:107
砸百鬼腳本 發布:2025-05-18 03:53:34 瀏覽:944
安卓手機如何拍視頻和蘋果一樣 發布:2025-05-18 03:40:47 瀏覽:741
為什麼安卓手機連不上蘋果7熱點 發布:2025-05-18 03:40:13 瀏覽:803
網卡訪問 發布:2025-05-18 03:35:04 瀏覽:511
接收和發送伺服器地址 發布:2025-05-18 03:33:48 瀏覽:372