Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[c++]Kopiowanie tablic

Ostatnio zmodyfikowano 2014-12-06 21:43
Autor Wiadomość
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
C/C++
for( int i = 0; i < r; i++ )
     A[ i ] = B[ i ];

 lub
C/C++
memcpy( A, B, sizeof( A ) );

czy znacie jakieś szybkie metody?
P-122320
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ć



P-122321
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?
P-122323
darko202
» 2014-12-06 11:34:28
poprawka
C/C++
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
B = C; // odtworzenie starego A

albo przekopiowanie całego fragmentu pamięci przeznaczonego na tablicę A w miejsce fragmentu pamięci zarezerwowanego dla tablicy B

podobnie jak próbuje to zrobić
http://forum.4programmers.net​/C_i_.NET​/187595-kopiowanie_fragmentu_pamieci_i_iteracja_tablicy

poczytaj
http://www.google.pl/url?sa=t​&rct=j&q=&esrc=s&frm=1​&source=web&cd=2&ved=0CCYQFjAB​&url=http%3A%2F%2Fstaff.iiar.pw​r.wroc.pl%2Frobert.wojcik%2Fdy​daktyka%2Fwyklad_c%2Finz%2FW_I​NZ_12.doc​&ei=ft-CVKTDCYXpUo-ogOAP​&usg=AFQjCNFsEC9D8LC8D-4RHnSsi​K2DZCGkLQ​&bvm=bv.80642063,d.ZWU
P-122324
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:

C/C++
//kopiuje 20 elementów
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.
P-122353
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ó
P-122360
Kaikso
» 2014-12-06 18:02:47
Możesz kopiować tablice pełnymi blokami np. tak:

C/C++
#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ć ;).
P-122370
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
C/C++
for( int i = 0; i < r; i++ )
     A[ i ] = B[ i ];

 lub
C/C++
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.
P-122411
« 1 »
  Strona 1 z 1