IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Rapidité des flux


Sujet :

C++

  1. #1
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut Rapidité des flux
    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

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Un point sur lequel il faut faire attention sont les mécanismes de cache du système qui peuvent biaiser tes mesures de perfs. A prendre en compte au moment où tu détermines ton protocole de test.

Discussions similaires

  1. Rapidité des Sockets ???
    Par sekaijin dans le forum Langage
    Réponses: 18
    Dernier message: 23/09/2008, 16h14
  2. Rapidité des DLL
    Par Ekinoks dans le forum Windows
    Réponses: 12
    Dernier message: 12/12/2005, 10h58
  3. [Indy] Client-serveur pour recevoir des flux videos
    Par Nicodemus dans le forum Web & réseau
    Réponses: 7
    Dernier message: 10/10/2005, 14h18
  4. [DOM] Comment créer des flux XML en java ?
    Par nean_j dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 27/04/2004, 12h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo