Cos wydajniejszego od BitArray

0

Do operacji na tabeli bajtowej chcąc operować na bitach używam BitArray jednak już przy 100k bajtów edytując każdy bit w pętli (jedna zmiana nic innego nie powoduje opóźnienia) trwa jakieś 30ms, chciał bym to skrócić i tu moje pytanie czy jest wydajniejszy sposób na to? ;]

0

Stwórz własną tablicę byte'ów albo intów i sam operuj na nich za pomocą operacji bitowych (w przypadku klasy BitArray możesz tracić na wywołaniach metod)? Zmieniaj wiele wartości na raz (korzystając z klasy BitArray zmiana kolejnych 32 bitów to 64 operacje, które sam możesz zredukować do jednej)? Zmień całkowicie algorytm?

1

Jeśli jedna zmiana bita w BitArray zajmuje 30 ms to, cytując klasyka, wiedz że coś się dzieje.
W szczególności, powinno to zajmować max kilkadziesiąt nanosekund.
Nieważne, pisałeś o wszystkim.

A poza tym co robisz dokładniej i jak wygląda algorytm? Może da się to lepiej napisać...

0

Np coś takiego jak zaprzeczenie bitowe, ale też rożne inne operacje jak zamiana losowych bitów w całej tabeli itp.

byte[] data = new byte[99999];
BitArray bits = new BitArray(data);
for (int i = 0; i < bits.Length; i ++)
bits[i] = !bits[i];
1

To właśnie jedna z operacji którą bardzo szybko możesz wykonać jedną z metod klasy BitArray:
http://msdn.microsoft.com/en-us/library/system.collections.bitarray.not.aspx
Powinno być nawet koło kilkudziesięciu razy szybsze.

Ma też sporo innych ciekawych funkcji - http://msdn.microsoft.com/en-us/library/eesz24dw.aspx

0

Wiem o tym, ja tylko przedstawiłem przykład, ale pisałem też o ważniejszej funkcji jaka robi mój program, losowo zmienia bity w całej tabeli, czego NIE MA w tej klasie

1

Wiem, wbrew pozorom czytałem Twój post.
No ale skoro zmieniasz losowo bity w całej tabeli, to znaczy że musisz mieć skądś te losowe wartości albo przynajmniej wyliczać indeksy do zmienienia. 100k bajtów do zmiany to nie tak dużo, ale jeśli doliczysz do tego to że masz 800k iteracji (cytując - edytując każdy bit w pętli) pętli, co sprowadza się do dodania 1 do zmiennej w pętli, porównania, skoku warunkowego (tak, sporo może tego kompilator zoptymalizować, ale JIT na razie nie jest zbyt agresywny pod tym względem - a jeśli przypadkiem źle sformułowałeś warunek zakończenia to pewnie nawet masz Array Bounds Check w każdej iteracji, bo JIT ma obecnie bardzo ścisłe wymagania przed wykonaniem ABC elimination), wyliczenia bitu do zmiany czy co tam robisz, zmiany bitu.

Może pokaż co faktycznie robisz, bo tak chyba do niczego nie dojdziemy. Tak czy inaczej BitArray nie ma jakiegoś wielkiego narzutu i optymalizowanie zacząłbym od czego innego.

0

Do tego dochodzi ABC w samej klasie BitArray, które raczej nie zostanie wyeliminowane, bo to już nie jest część runtime.

public bool Get(int index)
{
    if (index < 0 || index >= this.Length)
    {
        throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
    }
    else
    {
        return (this.m_array[index / 32] & 1 << (index % 32 & 31)) != 0;
    }
}
0

Temat dotyczy agresywnej optymalizacji. Gdybyś pokazał cały kod, konkretnie jak sobie algorytm wyobrażasz, to może dałoby się coś wymyśleć.
Ale tak w ogólnym przypadku trudno cokolwiek pomóc.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.