zennehoy
April 1st, 2008, 08:59 AM
Hello all,
I'm trying to write a simple and efficient logger class using template metaprogramming, but am failing miserably (at least on the efficiency part). I thought that an empty inline function would be optimized away, but apparantly it isn't; or I'm doing something else wrong. Here's the simplified code:
#include <windows.h>
#include <iostream>
#include <string>
template <bool T>
class logger { };
template <typename T>
inline logger<true> const &operator<<(logger<true> const &lg, T const &t) {
std::cout << t;
return lg;
}
inline logger<true> const &operator<<(logger<true> const &lg, std::basic_ostream<char, std::char_traits<char> >&(*t)(std::basic_ostream<char, std::char_traits<char> >&)) {
std::cout << t;
return lg;
}
template <typename T>
inline logger<false> const &operator<<(logger<false> const &lg, T const &t) {
return lg;
}
inline logger<false> const &operator<<(logger<false> const &lg, std::basic_ostream<char, std::char_traits<char> >&(*t)(std::basic_ostream<char, std::char_traits<char> >&)) {
return lg;
}
template <bool T>
inline logger<T> &log() { static logger<T> lgr; return lgr; }
int main() {
for(int j=0; j<10; ++j) {
unsigned int i = GetTickCount();
for(int i=0; i<100000000; ++i) {
// With this line takes 1500 ms, without takes 250 ms
log<false>() << "string" << 42 << std::endl;
}
i = GetTickCount() - i;
std::cout << i << std::endl;
}
return 0;
}
I would expect that the overloaded stream operator be compiled away, since it does nothing. Isn't that exactly what template metaprogramming is all about? Or am I doing something fundamentally wrong? I get practically identical poor results with both MSVC and GCC.
Thanks in advance for the help!
Zen
I'm trying to write a simple and efficient logger class using template metaprogramming, but am failing miserably (at least on the efficiency part). I thought that an empty inline function would be optimized away, but apparantly it isn't; or I'm doing something else wrong. Here's the simplified code:
#include <windows.h>
#include <iostream>
#include <string>
template <bool T>
class logger { };
template <typename T>
inline logger<true> const &operator<<(logger<true> const &lg, T const &t) {
std::cout << t;
return lg;
}
inline logger<true> const &operator<<(logger<true> const &lg, std::basic_ostream<char, std::char_traits<char> >&(*t)(std::basic_ostream<char, std::char_traits<char> >&)) {
std::cout << t;
return lg;
}
template <typename T>
inline logger<false> const &operator<<(logger<false> const &lg, T const &t) {
return lg;
}
inline logger<false> const &operator<<(logger<false> const &lg, std::basic_ostream<char, std::char_traits<char> >&(*t)(std::basic_ostream<char, std::char_traits<char> >&)) {
return lg;
}
template <bool T>
inline logger<T> &log() { static logger<T> lgr; return lgr; }
int main() {
for(int j=0; j<10; ++j) {
unsigned int i = GetTickCount();
for(int i=0; i<100000000; ++i) {
// With this line takes 1500 ms, without takes 250 ms
log<false>() << "string" << 42 << std::endl;
}
i = GetTickCount() - i;
std::cout << i << std::endl;
}
return 0;
}
I would expect that the overloaded stream operator be compiled away, since it does nothing. Isn't that exactly what template metaprogramming is all about? Or am I doing something fundamentally wrong? I get practically identical poor results with both MSVC and GCC.
Thanks in advance for the help!
Zen