Permettez-moi de réveiller cette discussion que je découvre à la lecture de celle-ci

A priori je ne vois pas ce qui pourrait être plus rapide que les appels à l'API de l'OS à condition de bufferizer (si l'OS ne le fait pas). Les std::filebuf, stdio ou autre font quand même des appels systèmes à un moment ou l'autre dans leur implémentation. Comparer ces différentes implémentations ne permet que de vérifier qu'il y en a de plus mauvaises que d'autres et qu'elles sont dépendantes du compilateur et de la RTL fournie.

Exemple de code bufferizé pour la lecture:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//paged file reader
template<class F, unsigned PS=4096u>
class file_reader: private F
{
public:
	typedef typename F::traits traits;
 
	typedef typename traits::byte byte;
 
	typedef typename traits::size_type size_type;
	typedef typename traits::offset_type offset_type;
 
private:
	offset_type f_currentoffset, f_nextoffset;
	byte *f_page;      //local buffer for page
	enum
	{
		e_pagesize=PS
	};
	unsigned f_loaded; //loaded page size
	unsigned f_pos;	   //position inside page
 
	//disable copy and assign
	file_reader(file_reader const &);
	file_reader & operator=(file_reader const &);
 
public:
	file_reader():
		f_currentoffset(0), f_nextoffset(0), f_page((byte *)0),
		f_loaded(e_pagesize), f_pos(f_loaded)
	{
		f_page=new byte[e_pagesize];
	}
	~file_reader()
	{
		if (*this) { try { close(); } catch(...) {} }
		delete[] f_page;
	}
	operator bool()
		{ return F::operator bool(); }
 
	bool fopen(_TCHAR const *path)
		{ return F::open(path, traits::e_mdread, traits::e_shread, traits::e_open); }
 
	bool close()
		{ return F::close(); }
 
	unsigned fread(void *buf, unsigned bufsize)
	{
		byte *bytedest=(byte *)buf;
		unsigned bufread=0;
		//check if file offset has been moved
		if (f_currentoffset!=f_nextoffset)
		{
			f_pos=static_cast<unsigned>(f_nextoffset % e_pagesize);
			f_nextoffset/=e_pagesize;
			f_nextoffset*=e_pagesize;
			if (f_nextoffset+e_pagesize!=f_currentoffset)
			{
				f_nextoffset=F::seek(f_nextoffset, traits::e_begin);
				F::read(f_page, e_pagesize, &f_loaded);
				f_currentoffset=(f_nextoffset+=f_loaded);
			}
			else
				f_nextoffset=f_currentoffset;
		}
		//read page by page
		while (bufsize)
		{
			if (f_pos<f_loaded)
			{
				unsigned copysize=f_loaded-f_pos;
				if (bufsize<copysize)
					copysize=bufsize;
				::memcpy(bytedest, &f_page[f_pos], copysize);
				bytedest+=copysize;
				f_pos+=copysize;
				bufread+=copysize;
				bufsize-=copysize;
			}
			else if (f_loaded==e_pagesize)
			{
				F::read(f_page, e_pagesize, &f_loaded);
				f_currentoffset=(f_nextoffset+=f_loaded);
				f_pos=0;
			}
			else
				break;//assume eof
		}
		return bufread;
	}
 
	offset_type fseek(offset_type offset)
	{
		//TODO check file is OK ?
		//offset is the file pointer from the beginning of file
		if (offset<0)
			throw std::runtime_error(std::string(STRA_LEN("file_reader::fseek, offset can't be negative\n")));
		//else if (F::size()<offset)
			//?;ok, accept to move file pointer beyond eof
		return (f_nextoffset=offset);
	}
 
	offset_type seek(offset_type offset, typename traits::seek_type sk)
	{
		//TODO check file is OK ?
		//offset is the file pointer from the beginning of file
		if (sk==traits::e_begin)
			;
		else if (sk==traits::e_current)
		{
			if (f_currentoffset!=f_nextoffset)
				offset+=f_nextoffset;//assume this is a consecutive seek() call
			else
				offset+=f_currentoffset-f_loaded+f_pos;
		}
		else
			throw std::runtime_error(std::string(STRA_LEN("file_reader::seek, unsupported seek_type\n")));
		return fseek(offset);
	}
 
	size_type size()
		{ return F::size(); }
};
A vous d'imaginer à quoi pourrait ressembler F (dans mon code ce n'est qu'un wrap des fonctions API de Windows, avec throw d'un runtime_error formaté et intelligible en cas d'erreur).

Je n'ai plus qu'à prendre le code de ram-000 et d'y ajouter le mien afin de voir si j'ai bien fait ça