anfängerprobleme mit sprintf
-
Tja, Ethon, du bist ein Genius.
-
Hacker schrieb:
Tja, Ethon, du bist ein Genius.
Lässt sich doch fixen. Bei 2x Speedup sollte das danach immer noch deutlich schneller sein. Mal ausprobieren.
-
Ethon schrieb:
Hacker schrieb:
Tja, Ethon, du bist ein Genius.
Lässt sich doch fixen. Bei 2x Speedup sollte das danach immer noch deutlich schneller sein. Mal ausprobieren.
Denkst du, dass, wenn du's an ISO/IEC schickst, sie es dann in den nächsten aufnehmen?
-
template<typename CharT, unsigned Base> std::basic_string<CharT> to_string(unsigned value) { static_assert(Base <= 16, "Unsupported Base"); CharT const lookup[] = { CharT('0'), CharT('1'), CharT('2'), CharT('3'), CharT('4'), CharT('5'), CharT('6'), CharT('7'), CharT('8'), CharT('9'), CharT('A'), CharT('B'), CharT('C'), CharT('D'), CharT('E'), CharT('F') }; std::array<CharT, std::numeric_limits<unsigned>::digits> buffer; auto iter = buffer.rbegin(); while(value > Base) { *iter = lookup[value % Base]; ++iter; value /= Base; } *iter = lookup[value]; return std::basic_string<CharT>(&(*iter), buffer.end()); }
Gefixt und noch schneller geworden.
Zum Konvertieren von 10.000.000 rand Werten braucht meine Funktion
real 0m11.909s
user 0m11.905s
sys 0m0.000sund std::to_string
real 0m26.853s
user 0m26.838s
sys 0m0.004sAlso, was ist der Unterschied?
-
Ethon!! Welchen Compiler benutzt du? Alter, mein GCC 4.7 meckert, dass to_string nicht deklariert ist (obwohl ich string implementiere). Was soll ich nur tun :schluchz:
-
Gcc 4.6.1
Kompiliert mit:
g++ -o test -O3 -march=native -std=c++0x test.cpp
Für std::to_string brauchst du <string> und den C++11 Switch.
-
Ethon schrieb:
Gcc 4.6.1
Kompiliert mit:
g++ -o test -O3 -march=native -std=c++0x test.cpp
Für std::to_string brauchst du <string> und den C++11 Switch.
Funktioniert immer noch nicht.
-
Ethon schrieb:
return std::basic_string<CharT>(&(*iter), buffer.end());
Bist Du sicher, daß basic_string diesen c-tor haben muss?
-
[quote="Swordfish"]
Ethon schrieb:
return std::basic_string<CharT>(&(*iter), buffer.end());
Bist Du sicher, daß basic_string diesen c-tor haben muss?
Jeder Container lässt sich garantiert mit einem Inputiteratorenpaar konstruieren, bin mir zu 100% sicher dass es auch für std::basic_string vorgeschrieben ist, man findet ihn auch in jeder C++ Referenz.
-
Ich hab auch noch eine Idee:
#include <algorithm> std::string to_hex_string(unsigned value) { static std::string hex; hex.clear(); do { if(value%16 >= 0 && value%16 < 10) hex += value%16 + '0'; else if(value%16 > 9 && value%16 < 17) hex += value%16 + 55; } while(value /= 16); std::reverse(hex.begin(), hex.end()); return hex; }
Swordfish: 414.683
Hacker: 1317.21
Meine: 284.66Außerdem braucht bei mir
std::string to_hex_string(unsigned value) { char buffer[sizeof(value) * 2 + 1]; sprintf(buffer,"%x", value); return std::string(buffer); }
sogar mit 2370.08 deutlich länger (mit -O3)...
-
Aaaaahh! Jetz' seh' ich's erst,
iter
ist auto ... da kann ich mein msvc stecken lassen ... *umschreibengeh'*Incocnito schrieb:
Außerdem braucht bei mir [sprintf] sogar mit 2370.08 deutlich länger (mit -O3)...
Grenzt an unmöglichkeit. Maschine?
// edit:
Swordfish: 594.549 Hacker: 1022.05 Ethon: 176.339 Ethon 2: 34.5288 Ethon 3: 49.962 Incocnito: 71.5127
// edit: Ethon 3 mit
return std::basic_string<CharT, std::char_traits< CharT > >( iter.base( ), buffer.end( ) );
-
Swordfish schrieb:
Ethon schrieb:
return std::basic_string<CharT>(&(*iter), buffer.end());
Bist Du sicher, daß basic_string diesen c-tor haben muss?
Er meint sicher
return std::basic_string<CharT>(iter.base(), buffer.end());
-
Ich hab Code::Blocks mit dem GCC 4.6.2 auf Windows 7 64 bit, duo 2.3ghz.
Das hier kompiliert
Und bekomm als Ausgabe
Ethon: ~2300
Ist irgendwie komisch.
-
[quote="Ethon"]
Swordfish schrieb:
Ethon schrieb:
return std::basic_string<CharT>(&(*iter), buffer.end());
Bist Du sicher, daß basic_string diesen c-tor haben muss?
Jeder Container lässt sich garantiert mit einem Inputiteratorenpaar konstruieren, bin mir zu 100% sicher dass es auch für std::basic_string vorgeschrieben ist, man findet ihn auch in jeder C++ Referenz.
Nur ist das da kein Inputiteratorenpaar.
-
[quote="Michael E."]
Ethon schrieb:
Swordfish schrieb:
Ethon schrieb:
return std::basic_string<CharT>(&(*iter), buffer.end());
Bist Du sicher, daß basic_string diesen c-tor haben muss?
Jeder Container lässt sich garantiert mit einem Inputiteratorenpaar konstruieren, bin mir zu 100% sicher dass es auch für std::basic_string vorgeschrieben ist, man findet ihn auch in jeder C++ Referenz.
Nur ist das da kein Inputiteratorenpaar.
Ein Zeiger unterstützt alle Operationen, die ein Inputiterator können muss, ist von daher also kompatibel.
Swordfish: 594.549 Hacker: 1022.05 Ethon: 176.339 Ethon 2: 34.5288 Ethon 3: 49.962 Incocnito: 71.5127
Interessant dass bei dir die dritte Version langsamer ist, beim GCC war sie schneller.
Er meint sicher
return std::basic_string<CharT>(iter.base(), buffer.end());
Was es nicht alles gibt, danke.
-
Ethon schrieb:
Ein Zeiger unterstützt alle Operationen, die ein Inputiterator können muss, ist von daher also kompatibel.
template<class InputIterator> basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
Also müssen die beiden Parameter denselben Typ haben. Da Paragraph 21.4.5 sagt, dass string::iterator implementation defined ist mit Bezug auf Paragraph 23.2, darfst du dann die Stelle suchen, an der steht, dass string::iterator einen nicht expliziten einstelligen Konstruktor mit einem Pointer als Parameter hat (keine Ahnung, obs die Garantie gibt, bin aber zu faul zum Suchen).
-
Lustig. Wenn ich diesen Code hier kompiliere, erhalte ich folgende Ergebnisse unterm GCC (-O3):
Swordfish: 418.613
Hacker: 1298.35
Ethon: 2315.44
Inco: 287.326Und wenn ich das ganze mit VS-2010 Express mache, hing mein Computer erstmal ne ganze Weile komplett, und dann hatte ich diese Ausgabe:
Swordfish: 18503.3
Hacker: 36503.5
Ethon: 5813.38
Inco: 12065.5Kann mir das jemand erklären
-
Also müssen die beiden Parameter denselben Typ haben.
Haben sie ja, 2x char*.
Da Paragraph 21.4.5 sagt, dass string::iterator implementation defined ist mit Bezug auf Paragraph 23.2, darfst du dann die Stelle suchen, an der steht, dass string::iterator einen nicht expliziten einstelligen Konstruktor mit einem Pointer als Parameter hat (keine Ahnung, obs die Garantie gibt, bin aber zu faul zum Suchen).
Wieso string::iterator? Der Konstruktor ist nicht umsonst templated, damit man jeden anderen Iterator übergeben kann, der dereferenziert einen passenden Char-Typ zurückgibt. Ein String-Iterator wird hier nie konstruiert.
Dank iterator_traits etc sind du unterschiede zwischen "richtigen" Iteratoren und Pointern nicht existent.
-
Incocnito schrieb:
Und wenn ich das ganze mit VS-2010 Express mache, hing mein Computer erstmal ne ganze Weile komplett, und dann hatte ich diese Ausgabe: [...]
Release kompilieren, von hand starten.
-
Sorry, buffer ist ja ein std::array und kein std::string. Die Argumentation bleibt aber dieselbe: buffer.end() ist ein array::iterator, &(*iter) ein Pointer, beide müssen denselben Typ haben.