Driv3r Temat założony przez niniejszego użytkownika |
[c++]Kopiowanie tablic » 2014-12-06 11:00:46 Witam Potrzebuje skopiować tablicę B do tablicy A (B tablica pomocnicza przechowująca liczby testowe, A tablica zawierająca liczby testowe na których działam i zamieniam), po każdym działaniu algorytmu muszę przekopiować dane z tablicy B(ponieważ badam czas działania algorytmu dla tych samych liczb), tylko tu się pojawia problem ponieważ działam na dużych rozmiarach tablicy i wykonuje w jednym przebiegu pętli 20 przekopiowań a w sumie w całym programie 2000 co bardzo niekorzystnie wpływa na czas, stosuje kopiowania w taki sposób for( int i = 0; i < r; i++ ) A[ i ] = B[ i ];
lub memcpy( A, B, sizeof( A ) );
czy znacie jakieś szybkie metody? |
|
darko202 |
» 2014-12-06 11:19:42 skoro kopiujesz cała tablicę to dlaczego nie zmienisz tylko wskaźnika w tablicy
int n; int * A; // wskaźnik tablicy dynamicznej int * B; int * C; A = new int[n]; // rezerwujemy obszar pamięci B = new int[n]; ...
*C = *A // zapamiętanie *A *A = *B; //kopiujemy cała tablicę *B = *C; // odtworzenie starego *A
jakoś tak to powinno wyglądać
|
|
Driv3r Temat założony przez niniejszego użytkownika |
» 2014-12-06 11:22:40 ale to nie będzie działało tak, że jak zmienie dane w jednej tablicy to zostaną zmienione we wszystkich "tablicach" i już nie będzie możliwe odtworzenie tablicy testowej? |
|
darko202 |
» 2014-12-06 11:34:28 |
|
Kaikso |
» 2014-12-06 15:25:28 @darko202 Ciągle to źle robisz. jeśli wszystkie tablice mają ten sam rozmiar to jedyną szybszą metodą będzie: void copy20( int * d, const int * s ) { d[ 0 ] = s[ 0 ]; d[ 1 ] = s[ 1 ]; d[ 2 ] = s[ 2 ]; d[ 3 ] = s[ 3 ]; d[ 4 ] = s[ 4 ]; d[ 5 ] = s[ 5 ]; d[ 6 ] = s[ 6 ]; d[ 7 ] = s[ 7 ]; d[ 8 ] = s[ 8 ]; d[ 9 ] = s[ 9 ]; d[ 10 ] = s[ 10 ]; d[ 11 ] = s[ 11 ]; d[ 12 ] = s[ 12 ]; d[ 13 ] = s[ 13 ]; d[ 14 ] = s[ 14 ]; d[ 15 ] = s[ 15 ]; d[ 16 ] = s[ 16 ]; d[ 17 ] = s[ 17 ]; d[ 18 ] = s[ 18 ]; d[ 19 ] = s[ 19 ]; }
Wada jest oczywista, kosztem wydajności rośnie rozmiar. Jeśli w programie stosujesz małe funkcje użyj przy nich modyfikator inline, oczywiście ma to taką samą wadę jak powyżej. |
|
Driv3r Temat założony przez niniejszego użytkownika |
» 2014-12-06 16:45:38 @Kaikso gorzej jak ma się duże tablice to jest w moim przypadku milion elementó |
|
Kaikso |
» 2014-12-06 18:02:47 Możesz kopiować tablice pełnymi blokami np. tak: #define __copy8( __dest8, __src8 ) \ do \ { \ unsigned char * __d8 = ( unsigned char * )__dest8; \ unsigned char * __s8 = ( unsigned char * )__src8; \ __d8[ 0 ] = __s8[ 0 ]; \ __d8[ 1 ] = __s8[ 1 ]; \ __d8[ 2 ] = __s8[ 2 ]; \ __d8[ 3 ] = __s8[ 3 ]; \ __d8[ 4 ] = __s8[ 4 ]; \ __d8[ 5 ] = __s8[ 5 ]; \ __d8[ 6 ] = __s8[ 6 ]; \ __d8[ 7 ] = __s8[ 7 ]; \ } while( false )
#define __copy64( __dest64, __src64 ) \ do \ { \ unsigned char * __d64 = ( unsigned char * )__dest64; \ unsigned char * __s64 = ( unsigned char * )__src64; \ __copy8( __d64 + ( 8 * 0 ), __s64 + ( 8 * 0 )); \ __copy8( __d64 + ( 8 * 1 ), __s64 + ( 8 * 1 )); \ __copy8( __d64 + ( 8 * 2 ), __s64 + ( 8 * 2 )); \ __copy8( __d64 + ( 8 * 3 ), __s64 + ( 8 * 3 )); \ __copy8( __d64 + ( 8 * 4 ), __s64 + ( 8 * 4 )); \ __copy8( __d64 + ( 8 * 5 ), __s64 + ( 8 * 5 )); \ __copy8( __d64 + ( 8 * 6 ), __s64 + ( 8 * 6 )); \ __copy8( __d64 + ( 8 * 7 ), __s64 + ( 8 * 7 )); \ } while( false )
#define __copy512( __dest512, __src512 ) \ do \ { \ unsigned char * __d512 = ( unsigned char * )__dest512; \ unsigned char * __s512 = ( unsigned char * )__src512; \ __copy64( __d512 + ( 64 * 0 ), __d512 + ( 64 * 0 )); \ __copy64( __d512 + ( 64 * 1 ), __d512 + ( 64 * 1 )); \ __copy64( __d512 + ( 64 * 2 ), __d512 + ( 64 * 2 )); \ __copy64( __d512 + ( 64 * 3 ), __d512 + ( 64 * 3 )); \ __copy64( __d512 + ( 64 * 4 ), __d512 + ( 64 * 4 )); \ __copy64( __d512 + ( 64 * 5 ), __d512 + ( 64 * 5 )); \ __copy64( __d512 + ( 64 * 6 ), __d512 + ( 64 * 6 )); \ __copy64( __d512 + ( 64 * 7 ), __d512 + ( 64 * 7 )); \ } while( false )
void * xncopy( void * dest, const void * src, size_t size ) { while( size >= 512 ) { __copy512( dest, src ); size -= 512; dest += 512; src += 512; } while( size >= 64 ) { __copy64( dest, src ); size -= 64; dest += 64; src += 64; } while( size >= 8 ) { __copy8( dest, src ); size -= 8; dest += 8; src += 8; } while( size-- > 0 ) * dest++ = * src++; return dest; }
To znacznie przyśpieszy program, ale znacznie zwiększy jego rozmiar :P, na szczęście nie na tyle by znacznie spowolnić jego ładowanie :), jedynie wydłuży się czas kompilacji. Parametry funkcji i wartość zwracana są analogiczne do memcpy(). Na dodatek jeśli w memcpy instrukcja przypisania występuje raz to w xncopy występuje ona 512 + 64 + 8 + 1 czyli 585, inne instrukcje które zostały analogicznie użyte to inkrementacja i dekrementacja, przypisanie sumy, pętle z porównaniem itp. nie stanowią tak dużej różnicy więc nie trzeba się nimi martwić ;). |
|
Elaine |
» 2014-12-06 21:43:58 Potrzebuje skopiować tablicę B do tablicy A (B tablica pomocnicza przechowująca liczby testowe, A tablica zawierająca liczby testowe na których działam i zamieniam), po każdym działaniu algorytmu muszę przekopiować dane z tablicy B(ponieważ badam czas działania algorytmu dla tych samych liczb), tylko tu się pojawia problem ponieważ działam na dużych rozmiarach tablicy i wykonuje w jednym przebiegu pętli 20 przekopiowań a w sumie w całym programie 2000 co bardzo niekorzystnie wpływa na czas, stosuje kopiowania w taki sposób
for( int i = 0; i < r; i++ ) A[ i ] = B[ i ];
lub
memcpy( A, B, sizeof( A ) );
czy znacie jakieś szybkie metody? |
Tak: użyć takiej struktury danych, by nie trzeba było ciągle kopiować. Jeśli z jakiegoś powodu nie możesz lub nie chcesz, to najszybszą metodą kopiowania jest prawie na pewno memcpy. |
|
« 1 » |