2017-03-26 21 views
5

सी और जंग के बीच फ़ाइल I/O प्रदर्शन की तुलना करने के लिए, मैं 100,000,000 बार फ़ाइल में "परीक्षण" लिखता हूं और 100,000,000 बार फ़ाइल से 4 बाइट्स पढ़ता हूं।जंग की तुलना में जंग फ़ाइल I/O बहुत धीमी है क्या कुछ गलत है?

सी की तुलना में, जंग कोड लिखने के लिए sys समय के 450 गुना से अधिक समय और पढ़ने के लिए 140 बार खर्च किया।

मुझे संदेह है कि तेज़ I/O प्राप्त करने के बेहतर तरीके हैं; मैं जंग में फ़ाइल I/O के प्रदर्शन में सुधार कैसे करूं? लिखने के लिए

$ rustc --version 
rustc 1.16.0 
$ rustc rswrite.rs -C opt-level=3 # Rust for writing 
$ time ./rswrite 
real 1m8.411s 
user 0m3.817s 
sys  1m4.533s 
$ rustc rsread.rs -C opt-level=3 # Rust for reading 
$ time ./rsread 
real 0m18.077s 
user 0m2.130s 
sys  0m15.910s 
$ gcc -O3 cwrite.c -ocwrite # C for writing 
$ time ./cwrite 
real 0m1.564s 
user 0m1.397s 
sys  0m0.143s 
$ gcc -O3 cread.c -ocread # C for reading 
$ time ./cread 
real 0m1.353s 
user 0m1.240s 
sys  0m0.113s 

जंग कोड: पढ़ने के लिए

#include <stdio.h> 
#define N 100000000 
int main() 
{ 
    const char *teststr = "test"; 
    FILE *fp = fopen("c.dump", "wb"); 
    unsigned long long i; 
    for (i=0; i<N; i++) fwrite(teststr, 4, 1, fp); 
    fclose(fp); 
    return 0; 
} 

सी कोड: पढ़ने के लिए

use std::fs; 
use std::io::Write; 
fn main() { 
    let b = b"test"; 
    let mut f = fs::File::create("rs.dump").unwrap(); 
    for _ in 0 .. 100_000_000 { 
     f.write(b).unwrap(); 
    } 
} 

जंग कोड: लेखन के लिए

use std::{fs, mem}; 
use std::io::Read; 
fn main() { 
    let mut f = fs::File::open("rs.dump").unwrap(); 
    let mut b: [u8; 4] = unsafe { mem::uninitialized() }; 
    for _ in 0 .. 100_000_000 { 
     f.read_exact(&mut b).unwrap(); 
    } 
} 

सी कोड

#include <stdio.h> 
#define N 100000000 

int main() { 
    FILE *fp = fopen("c.dump", "rb"); 
    long long i; 
    char buf[4]; 
    for (i=0; i<N; i++) fread(buf, 4, 1, fp); 
    fclose(fp); 
    return 0; 
} 
+7

आपका सी कार्यक्रम आईओ बफ़र उपयोग कर रही है के रूप में है। आपका जंग कार्यक्रम नहीं है। – BurntSushi5

+1

जंग के नीचे उन 'sys' बार भयानक हैं। यदि आप लिनक्स पर चल रहे हैं, तो प्रक्रियाओं को 'स्ट्रेस' के तहत चलाएं और देखें कि कौन सी सिस्टम वास्तव में विभिन्न प्रक्रियाओं को कॉल कर रही है। –

+0

@AndrewHenle: अच्छी सलाह; यह प्रकट होगा कि I/O को जंग में डिफ़ॉल्ट रूप से buffered नहीं किया गया है, जिसका अर्थ है कि पूरी तरह से सिस्टम कॉल का मतलब है। –

उत्तर

8

मेरा जंग कार्यक्रम buffered आईओ का उपयोग नहीं कर रहा था। BurntSushi5 और एंड्रयू हेनले की टिप्पणियों के लिए धन्यवाद, समस्या हल हो गई है।

$ strace ./rswrite 
write(3, "test", 4)      = 4 
write(3, "test", 4)      = 4 
... 
$ strace ./rswrite 
read(3, "test", 4)      = 4 
read(3, "test", 4)      = 4 
... 

मैं कोड संशोधित:

use std::fs; 
use std::io::{BufWriter, Write}; 
fn main() { 
    let b = b"test"; 
    /**** Use std::io::BufWriter ****/ 
    let mut f = BufWriter::new(fs::File::create("rs.dump").unwrap()); 
    for _ in 0 .. 100_000_000 { 
     f.write(b).unwrap(); 
    } 
} 

और

use std::{fs, mem}; 
use std::io::{BufReader, Read}; 
fn main() { 
    /**** Use std::io::BufReader ****/ 
    let mut f = BufReader::new(fs::File::open("rs.dump").unwrap()); 
    let mut b: [u8; 4] = unsafe { mem::uninitialized() }; 
    for _ in 0 .. 100_000_000 { 
     f.read_exact(&mut b).unwrap(); 
    } 
} 

अब, मैं/हे बफ़र कर रहा है।

write(3, "testtesttesttesttesttesttesttest"..., 8192) = 8192 
write(3, "testtesttesttesttesttesttesttest"..., 8192) = 8192 
... 

प्रदर्शन के रूप में तेजी से सी

$ time ./rswrite 
real 0m1.341s 
user 0m0.213s 
sys  0m0.200s 
$ time ./rsread_buf 
real 0m0.596s 
user 0m0.540s 
sys  0m0.050s