2016-05-28 17 views
8

Il codice qui sotto impiega per sempre (beh, un lungo periodo di tempo) per compilare in g ++ 6.1.0, rispetto a g ++ 4.8.3. È un bug del compilatore? O qualcosa di stupido nel codice? (Stupider che usare fixed e showpoint dove non ci sono valori in virgola mobile ...).g ++ 6,1 regressione del tempo di compilazione?

g ++ 4.8:

$ tempo ~/dev/compilatori/linux-x86_64-2.10.1/gnu4.8.3/bin/g ++ -D_REENTRANT -fPIC -Wall -Wextra -Wno-inutilizzato -parameter -Werror -Wno-inutilizzato-local-typedef -m64 -Woverloaded-virtual--Wno deprecato -fvisibility -fvisibility-inlines-hidden = hidden -std = C++ 11 ostreamtest.cpp -c

reale 0m0.451s

g ++ 6.1:

$ tempo ~/dev/compilatori/linux-x86_64-2.10.1/gnu6.1.0/bin/g ++ -D_REENTRANT -fPIC -Wall -Wextra -Wno-inutilizzato parametri - Werror -Wno-inutilizzato-local-typedef -m64 -Woverloaded-virtual--Wno deprecato -fvisibility -fvisibility-inlines-hidden = hidden -std = C++ 11 ostreamtest.cpp -c

reale 15m36.033s

ostreamtest.cpp:

#include <iostream> 
#include <iomanip> 
#include <ostream> 

typedef long long int64; 

class IOStreamWrapper 
{ 
public: 
    /// get/set ALL format flags 
    virtual std::ios_base::fmtflags flags() const; 
    virtual std::ios_base::fmtflags flags(std::ios_base::fmtflags flags); 

    /// set specific format flags 
    virtual std::ios_base::fmtflags setf(std::ios_base::fmtflags flags); 
    virtual std::ios_base::fmtflags setf(std::ios_base::fmtflags flags, std::ios_base::fmtflags mask); 

    /// unset specific format flags 
    virtual void unsetf(std::ios_base::fmtflags mask); 

    /// get/set precision 
    virtual std::streamsize precision() const; 
    virtual std::streamsize precision(std::streamsize precision); 

    /// get/set width 
    virtual std::streamsize width() const; 
    virtual std::streamsize width(std::streamsize wide); 

    /// get/set fill char 
    virtual char fill() const; 
    virtual char fill(char c); 

    /// stream error states 
    virtual bool good(); 
    virtual bool bad(); 
    virtual bool fail(); 
    virtual bool eof(); 
    virtual void clear(); 

    // Forward conversion to bool to the real istream. 
    virtual operator int(); 

    // forward operators void* (returns !fail()) 
    virtual operator void*(); 

    // forward operator !() (returns fail()) 
    virtual bool operator !(); 

    /// dummy method which allows use of broadcast and nobroadcast manipulators 
    /// in the InputFileStream and OutputFileStream classes. Not perfect but the 
    /// only way I could this to work. 
    virtual void setBroadcastFlag(bool const &flag = true) { return; } 
protected: 
    // Construct class to reference a real istream. All methods and 
    // operators will be forwarded. 
    IOStreamWrapper(std::ios &ios); 
    IOStreamWrapper(IOStreamWrapper const &r); 
    virtual ~IOStreamWrapper() {} 

    // Reference to the real ostream. 
    std::ios  & iostr()  { return _iostr; } 
    std::ios const & iostr() const { return _iostr; } 
private: 
    // Reference to the real iostream. 
    std::ios &_iostr; 

    IOStreamWrapper &operator=(IOStreamWrapper const &r); // Not Implemented. 
}; 


class Indent; 

class OStreamWrapper: public IOStreamWrapper 
{ 
public: 
    // Construct class to reference a real ostream. All methods and 
    // operators will be forwarded. 
    OStreamWrapper(std::ostream &os); 
    OStreamWrapper(OStreamWrapper const &r); 
    virtual ~OStreamWrapper() {} 

    // Type for a fake endl. 
    struct EndlType {}; 

    // Forward this output operator to the real ostream. 
    OStreamWrapper & operator << (EndlType const &); 
    OStreamWrapper & operator << (Indent const &); 

    // wrappers for ostream global functions 
    virtual OStreamWrapper & operator<<(char c); 
    virtual OStreamWrapper & operator<<(unsigned char c); 
    virtual OStreamWrapper & operator<<(char const * s); 
    virtual OStreamWrapper & operator<<(unsigned char const * s); 
    virtual OStreamWrapper & operator<<(std::string); 

    // wrappers for ostream member functions 
    virtual OStreamWrapper & operator << (bool); 
    virtual OStreamWrapper & operator << (short); 
    virtual OStreamWrapper & operator << (unsigned short); 
    virtual OStreamWrapper & operator << (int); 
    virtual OStreamWrapper & operator << (unsigned int); 
    virtual OStreamWrapper & operator << (long); 
    virtual OStreamWrapper & operator << (unsigned long); 
    virtual OStreamWrapper & operator << (long long); 
    virtual OStreamWrapper & operator << (unsigned long long); 
    virtual OStreamWrapper & operator << (float); 
    virtual OStreamWrapper & operator << (double); 
    virtual OStreamWrapper & operator << (long double); 
    virtual OStreamWrapper & operator << (void*); 
    virtual OStreamWrapper & operator << (std::streambuf* sb); 
    virtual OStreamWrapper & operator << (OStreamWrapper &(*manpip)(OStreamWrapper &)); 
    virtual OStreamWrapper & operator << (std::ostream &(*manpip)(std::ostream &)); 
    virtual OStreamWrapper & operator << (std::ios &(*manip)(std::ios &)); 
    virtual OStreamWrapper & operator << (std::ios_base &(*manip)(std::ios_base &)); 

    OStreamWrapper & operator << (void  (*)(void*)); 
    OStreamWrapper & operator << (void*  (*)(void*)); 
    OStreamWrapper & operator << (int   (*)(void*)); 
    OStreamWrapper & operator << (int*  (*)(void*)); 
    OStreamWrapper & operator << (float*  (*)(void*)); 
    OStreamWrapper & operator << (char const* (*)(void*)); 
    OStreamWrapper & operator << (void  (*)(void*, int*)); 

    // Forward ostream methods directly to the ostream 
    virtual OStreamWrapper & write(char const*, std::streamsize); 
    virtual OStreamWrapper & flush(); 
    virtual OStreamWrapper & put(char c); 
    virtual OStreamWrapper & seekp(std::streampos pos); 
    virtual OStreamWrapper & seekp(std::streamoff offset, std::ios_base::seekdir dir); 
    virtual std::streampos tellp(); 

    /// switch for broadcast flag in InputFileStream class 
    static OStreamWrapper & broadcast(OStreamWrapper &); 
    static OStreamWrapper & nobroadcast(OStreamWrapper &); 

    // Get a reference to the real ostream. 
    std::ostream & GetOStream(); 

    // Allow conversion to the real ostream type. This allows an 
    // instance of OStreamWrapper to look like ostream when passing to a 
    // function argument. 
    operator std::ostream&(); 

    // Implementation detail to allow macros to provide an endl that may 
    // or may not be used. 
    static void UseEndl(EndlType const &) {} 

    // wrap std manipulators 
    class setw{ 
    public: 
    explicit setw(int const &i) : _i(i) {} 
    private: 
    friend OStreamWrapper & operator<<(OStreamWrapper &ib, setw const &m) 
    { 
     ib.width(m._i); 
     return ib; 
    } 
    int _i; 
    }; 
    class setprecision{ 
    public: 
    explicit setprecision(int const &i) : _i(i) {} 
    private: 
    friend OStreamWrapper & operator<<(OStreamWrapper &ib, setprecision const &m) 
    { 
     ib.precision(m._i); 
     return ib; 
    } 
    int _i; 
    }; 
    class setfill{ 
    public: 
    explicit setfill(char c) : _c(c) {} 
    private: 
    friend OStreamWrapper & operator<<(OStreamWrapper &ib, setfill const &m) 
    { 
     ib.fill(m._c); 
     return ib; 
    } 
    char _c; 
    }; 
    class setiosflag{ 
    public: 
    explicit setiosflag(std::ios_base::fmtflags mask) : _mask(mask) {} 
    private: 
    friend OStreamWrapper & operator<<(OStreamWrapper &ib, setiosflag const &m) 
    { 
     ib.setf(m._mask); 
     return ib; 
    } 
    std::ios_base::fmtflags _mask; 
    }; 
    class resetiosflag{ 
    public: 
    explicit resetiosflag(std::ios_base::fmtflags mask) : _mask(mask) {} 
    private: 
    friend OStreamWrapper & operator<<(OStreamWrapper &ib, resetiosflag const &m) 
    { 
     ib.unsetf(m._mask); 
     return ib; 
    } 
    std::ios_base::fmtflags _mask; 
    }; 
protected: 
    // Reference to the real ostream. 
    std::ostream  & ostr()  { return _ostr; } 
    std::ostream const & ostr() const { return _ostr; } 
private: 
    // Reference to the real ostream. 
    std::ostream &_ostr; 

    OStreamWrapper & operator=(OStreamWrapper const &r); // Not Implemented. 
}; 


void 
printProcessTableData(OStreamWrapper &out, 
    int const maxLen, 
    int const columnWidth, 
    int const nColumns, 
    std::string const &tag, 
    double const resMem, 
    double const addedResMem, 
    double const addedResHWM, 
    int const c) 
{ 
    out << OStreamWrapper::setw(maxLen - 2) 
     << std::left 
     << "| " + tag.substr(0,maxLen-4) 
     << std::right 
     << OStreamWrapper::setw(2) 
     << " |" 
     << OStreamWrapper::setw(columnWidth - 19) 
     << c 
     << OStreamWrapper::setw(2) 
     << " |" 
     << OStreamWrapper::setw(columnWidth - 8) 
     << std::fixed 
     << std::showpoint 
     << int64(resMem) 
     << OStreamWrapper::setw(2) 
     << " |" 
     << OStreamWrapper::setw(columnWidth - 6) 
     << std::fixed 
     << std::showpoint 
     << int64(addedResMem) 
     << OStreamWrapper::setw(2) 
     << " |" 
     << OStreamWrapper::setw(columnWidth - 2) 
     << std::fixed 
     << std::showpoint 
     << int64(addedResHWM) 
     << OStreamWrapper::setw(2) 
     << " |" 
     << std::endl; 
} 
+0

prende 0,7 secondi con gcc 5.3.1. Non riesco davvero a vedere nulla qui che possa dare al compilatore le modifiche. Altre analisi sono in ordine: se questa è legata alla CPU o all'I/O. Usa "top" per vedere dove ruota esattamente la compilation - nel preprocessore, nel compilatore vero e proprio, in 'as', ecc ... –

+0

Grazie per dare un'occhiata. cc1plus usa il 99,9% della CPU per quasi tutto il tempo. Aggiungere il flag -v non fornisce nulla di interessante. –

+1

Bene, questo codice è abbastanza piccolo da essere [scaricato in bugzilla di gcc] (https://gcc.gnu.org/bugzilla/). È molto probabile che qui si ottengano risultati migliori rispetto a stackoverflow.com –

risposta

Problemi correlati