Integer in String aber "manuell"
-
Ceos schrieb:
ich brauch eine effizizente lösung um einen integer in ein char array ala string zu bekommen, aber mir steht dabei leider keine sinnvolle bibliothek zur verfügung!
gleich als string einlesen und feddich
-
au haua aua schrieb:
Ceos schrieb:
ich brauch eine effizizente lösung um einen integer in ein char array ala string zu bekommen, aber mir steht dabei leider keine sinnvolle bibliothek zur verfügung!
gleich als string einlesen und feddich
Zeig mal! (Integer in String aber "manuell")
-
such mal im internet nach 'hackers delight division by constants'. es gibt's tricks, wie man divison und modulus mit shifts und additionen hinbekommt. geht zwar nicht mit jedem divisor, aber mit 5 und 10 auf jeden fall. damit kannst du die / und % loswerden, was eventuell schneller sein kann.
-
; void int_to_str( char *dst, int src ) { sub esp,0Ch ; size_t i = log10( src ) + 1; fld qword ptr [__real@40c81c8000000000 (862100h)] push ebx push esi mov ebx,3039h call _CIlog10 (861880h) fadd qword ptr [__real@3ff0000000000000 (8620F8h)] fnstcw word ptr [esp+0Ah] movzx eax,word ptr [esp+0Ah] or eax,0C00h mov dword ptr [esp+0Ch],eax fldcw word ptr [esp+0Ch] fistp qword ptr [esp+0Ch] mov eax,dword ptr [esp+0Ch] ; dst[ i-- ] = '\0'; mov byte ptr [eax+3039h],0 dec eax fldcw word ptr [esp+0Ah] ; for( ; src; src /= 10, --i ) { ; dst[ i ] = '0' + ( src % 10 ); lea esi,[eax+3039h] jmp int_to_str+50h (861050h) lea ecx,[ecx] mov eax,66666667h imul ebx sar edx,2 mov ecx,edx shr ecx,1Fh add ecx,edx mov al,cl mov dl,0Ah imul dl sub bl,al add bl,30h mov byte ptr [esi],bl mov ebx,ecx dec esi test ebx,ebx jne int_to_str+50h (861050h) ; } pop esi pop ebx ; }
Hilf mir mal kurz, ich seh' hier keine Division...
#include <stdlib.h> #include <time.h> #include <stdio.h> #include <math.h> #include <intrin.h> #define MAX_NUMBERS 100000 void int_to_str_sprintf( char *dst, int src ) { sprintf( dst, "%i", src ); } void int_to_str_log( char *dst, int src ) { size_t i = ( size_t ) log10( src ) + 1; dst[ 0 ] = '0'; dst[ i-- ] = '\0'; for( ; src; src /= 10, --i ) { dst[ i ] = '0' + ( src % 10 ); } } void int_to_str_loop( char *dst, int src ) { size_t i = 1; int tmp = src; for( ; tmp; tmp /= 10, ++i ); dst[ 0 ] = '0'; dst[ i-- ] = '\0'; for( ; src; src /= 10, --i ) { dst[ i ] = '0' + ( src % 10 ); } } int main( void ) { int number[ MAX_NUMBERS ]; char string[ 10 ]; unsigned __int64 start, stop; size_t i = 0; srand( ( unsigned int ) time( 0 ) ); for( ; i < MAX_NUMBERS; number[ i++ ] = rand( ) ); start = __rdtsc( ); for( i = 0; i < MAX_NUMBERS; ++i ) { int_to_str_sprintf( string, number[ i ] ); } stop = __rdtsc( ); printf( "sprintf: %8u\n", ( stop - start ) / MAX_NUMBERS ); start = __rdtsc( ); for( i = 0; i < MAX_NUMBERS; ++i ) { int_to_str_log( string, number[ i ] ); } stop = __rdtsc( ); printf( "log: %8u\n", ( stop - start ) / MAX_NUMBERS ); start = __rdtsc( ); for( i = 0; i < MAX_NUMBERS; ++i ) { int_to_str_loop( string, number[ i ] ); } stop = __rdtsc( ); printf( "loop: %8u\n", ( stop - start ) / MAX_NUMBERS ); }
Ausgabe:
sprintf: 775 log: 167 loop: 97
Mit 'nem lookup table gehts wahrscheinlich noch schneller... Wofür?
cheers, Swordfish
PS: Aja, Intel Merom Stepping M0, 32kB/32kB L1, 2MB L2
-
Swordfish schrieb:
Hilf mir mal kurz, ich seh' hier keine Division...
das zeichen / heisst 'dividieren' und das % heisst 'dividiere und gib mir den rest'. beides kann sehr lahm sein wobei letzteres das schlimmere von beiden ist.
-
foobar fread schrieb:
das zeichen / heisst 'dividieren' und das % heisst 'dividiere und gib mir den rest'.
Na gell, wirklich? Dann verrat' ich Dir auch mal ne "Neuigkeit": Diese Art von Zeichen heißen Operatoren...
Du gehst mir schön langsam richtig auf den Keks: Wo siehst du im vom Compiler erzeugten Maschinencode ein
div
? Wozu denkst du, mach ich mir die Mühe, das Assembly zu posten!?
-
Swordfish schrieb:
Wozu denkst du, mach ich mir die Mühe, das Assembly zu posten!?
na, weil du bestimmt ganz genau weisst, dass der OP ein X86 derivat und den gleichen compiler benutzt wie du. mit dem asm-code ist ihm wirklich sehr geholfen.
-
Swordfish schrieb:
Hilf mir mal kurz, ich seh' hier keine Division...
... sar edx,2 ...
:p
-
x86-freak schrieb:
na, weil du bestimmt ganz genau weisst, dass der OP ein X86 derivat und den gleichen compiler benutzt wie du. mit dem asm-code ist ihm wirklich sehr geholfen.
Nein, um zu zeigen, dass heutige Compiler schlau genug sind, selbst zu optimieren und deinen Bitshift-Vorschlag als das zu entlarven, was er ist: Unnötig.
Gut - eine Division hab' ich tatsächlich übersehen. Poste Du doch mal Deine "Traumvorstellung" einer solchen Funktion, freaky.
cheers, Swordfish
-
Swordfish schrieb:
Nein, um zu zeigen, dass heutige Compiler schlau genug sind, selbst zu optimieren...
schlau ist relativ. und die möglichkeiten eines vc++ auf x86 könnte sein compiler auf seiner maschine eben nicht haben, z.b. für division und modulo subroutinen aufrufen usw, die architekturbedingt relativ aufwendige berechnungen machen.