為什麼 read() 比 getc() 慢?

為什麼 read() 比 getc() 慢?

為什麼read比 慢getc

例如,這個:

for (;;) {
        chr++;
        amr=read(file1, &wc1, 1);
        amr2=read(file2, &wc2, 1);
        if (wc1 == wc2) {
            if (wc1 == '\n')
                line++;
            if (amr == 0) {
                if (eflg)
                    return (1);
                return (0);
            }
            continue;
        }

比那慢:

for (;;) {
    chr++;
    c1 = getc(file1);
    c2 = getc(file2);
    if (c1 == c2) {
        if (c1 == '\n')
            line++;
        if (c1 == EOF) {
            if (eflg)
                return (1);
            return (0);
        }
        continue;
    }

getc使用read系統調用,為什麼會慢呢?

答案1

由於 getc() 在傳回讀取的資料之前對其進行緩衝,因此對 的呼叫getc()不一定會導致對read().read()是一個系統調用,它比普通函數調用需要更長的時間來完成,因為核心有更多的操作要做。當你進入核心空間時,它會改變你的堆疊,保存所有上下文,處理要屏蔽的中斷,而在另一端,當它完成時,它會恢復上下文,中斷,將你的用戶空間堆疊放回去。這就是為什麼getc() 是首選的原因,因為如果您已經有可用的緩衝數據,它可以節省大量開銷。

答案2

歸根結底,磁碟讀取是面向區塊的:要從磁碟讀取單一位元組,硬體最終會讀取一個位元組區塊(512 或 1024 或某個數量),緩衝所有這些,並將其傳遞給核心。如果您從檔案的區塊 0 讀取檔案的位元組 0,請做一些工作,然後從檔案讀取位元組 1,核心最終可能會再次讀取檔案的區塊 0。再次針對位元組 2,再次針對位元組 3。

每次read()呼叫也必須將 CPU 從使用者態變更為核心態。記憶體映射至少會改變。可能還會發生很多其他不那麼明顯的事情。這也需要時間。

系統read()呼叫會變更 CPU 狀態,並且可能需要磁碟 I/O。getc()可以在用戶空間緩衝整個磁碟區塊(或更多),因此可能 512 呼叫會getc()導致核心讀取單一磁碟區塊,並進行單一狀態變更。如果您查看,stdio.h您會發現一個常數宏,該常數應該是對磁碟上檔案或系統呼叫的BUFSIZ有效(磁碟區塊倍數)大小。read()write()

相關內容