Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

dział ogólny

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Cyfrowy Baron » piątek, 8 stycznia 2010, 14:29

Robię to tak:

Kod: Zaznacz cały
    int iFileHandle;
   int iFileLength;
   int iBytesRead;
   int iBytesWrite = 0;
   char *pszBuffer;
   wstring wstr;

   locale loc(".ACP");
   const ctype<wchar_t> &ct = use_facet<ctype<wchar_t> >(loc);

    if(OpenDialog1->Execute())
    {
     try
      {
       iFileHandle = FileOpen(OpenDialog1->FileName, fmOpenRead);
       iFileLength = FileSeek(iFileHandle, 0, 2);
      FileSeek(iFileHandle, 0, 0);
      pszBuffer = new char[iFileLength+1];

      iBytesRead = FileRead(iFileHandle, pszBuffer, iFileLength);
      FileClose(iFileHandle);

      wstr.reserve(iBytesRead);
      for(unsigned i = 0; i < iBytesRead; ++i)
      {
      wchar_t wc = ct.widen(pszBuffer[i]);
      bool ok = ct.is(ctype<wchar_t>::alpha | ctype<wchar_t>::digit | ctype<wchar_t>::punct,wc);
      if(!ok) wc = 0x2588;
      wstr[i] += wc;
      }

      Memo1->Lines->SetText( const_cast<wchar_t*>( wstr.c_str() ) );
      delete [] pszBuffer;
       }
       catch(...)
      {
       Application->MessageBox( L"Can't perform one of the following file operations: Open, Seek, Read, Close.", L"File Error", IDOK);
      }
   }


Wczytywanie rzeczywiście przebiega dość szybko. Jak sie okazało u mnie program antywirusowy generował opóźnienie.

Różnica pomiędzy wstring i UnicodeString jest niewielka. Plik 20 MB - wstring = 26,217 sek.; UnicodeString = 26.648 sek.
Jak widać moje wyniki różnią się od waszych, gdyż UnicodeString jest wolniejszy. Są to oczywiście tylko pomiary porównawcze, gdyż w tle pracowały inne programu, które angażowały procesor w około 20 procentach, ale to tylko pokazuje, że nie ma większego znaczenia którego typu się użyje.

Lepsze wyniki uzyskałem stosując funkcję SetTexBuf zamiast SetText - wstring = 25,979 sek.

Kod: Zaznacz cały
Memo1->SetTextBuf(const_cast<wchar_t*>( wstr.c_str() ));


Jeszcze lepsze wyniki wstring = 22,368 sek. uzyskałem zastępując Memo obiektem RichEdit z WordWrap i PlainText ustawionymi na false.

Co ciekawe samo wykonanie kodu, bez przepisywania do Memo czy RichEdit na pliku 20 MB trwało około 6 sek.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » sobota, 9 stycznia 2010, 12:20

polymorphism napisał(a):Czyli wstring jest prawie 2x szybszy od VCL-owej wersji stringa.


przepraszam, pomyliłem się, zrobiłem tamten test w Debug + CodeGuard, nie w Release.
Poprawka (po 3 testy):

UnicodeString:
us.c_str()[i] + SetLength(): 687, 688, 687
us+=: 1875, 1812, 1796
us[i+1] + SetLength(): 922, 938, 937


wstring:
ws+= + Reserve(): 2157, 2203, 2203, ,873
ws[i] + Resize(): 688, 672, 672, 547
ws.at(i) + Resize(): 703, 704, 703

Na czerwono wstring w DEBUG, nie rozumiem tego :shock:
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    Windows XPOpera

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » sobota, 9 stycznia 2010, 13:23

No faktycznie, coś dziwne te czasy. Nie spotkałem się jeszcze z czymś takim, żeby wersja release była ponad 2x wolniejsza od wersji debug.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Cyfrowy Baron » sobota, 9 stycznia 2010, 13:32

No faktycznie, coś dziwne te czasy. Nie spotkałem się jeszcze z czymś takim, żeby wersja release była ponad 2x wolniejsza od wersji debug.


To chyba tylko u was. U mnie release jest 3.5 raza szybsze od debug.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » sobota, 9 stycznia 2010, 13:38

Nie "u was", bo u mnie różnica między debug a release jest około sekundowa (10MB), na korzyść tej drugiej oczywiście.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » niedziela, 10 stycznia 2010, 15:28

Poprzestawiałem jakoś niechcący ustawiania dla Release i wyszły mi głupoty. Utworzyłem nowy projekt i teraz wyniki powinny być dobre:

UnicodeString:
us.c_str()[i] + SetLength(): 422
us+=: 1516
us[i+1] + SetLength(): 609


wstring:
ws+= + Reserve(): 562
ws[i] + Resize(): 453
ws.at(i) + Resize(): 472
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    Windows XPOpera

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » niedziela, 10 stycznia 2010, 19:29

O, teraz ma to sens. Jak widać, UnicodeString gorzej zarządza pamięcią, jest prawie 3x wolniejszy od wstringa.



Tak nawiasem:
us.c_str()[i] = ...

ta konstrukcja jest zła.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » poniedziałek, 11 stycznia 2010, 10:30

polymorphism napisał(a):Tak nawiasem:
us.c_str()[i] = ...

ta konstrukcja jest zła.


wiem , ale brak const (w opisie jest w deklaracji/kodzie - nie) przy wchar_t* może zachęcać to takich eksperymentów ;) i jest zastanawiający. Chciałem sprawdzić ile "kosztuje" to co jest w operatorze []:

Kod: Zaznacz cały
   wchar_t& __fastcall operator [](const int idx)
    {
      ThrowIfOutOfRange(idx);   // Should Range-checking be optional to avoid overhead ??
      Unique();                 // Ensure we're not ref-counted (and Unicode)
      return Data[idx-1];
    }


To co jest w helpie można przetłumaczyć jako zakaz ;) ?
The System::UnicodeString::c_str method is intended primarily for reading the value of the System::UnicodeString. To modify the System::UnicodeString’s value, use the [] operator or System::UnicodeString methods such as System::UnicodeString::Insert and System::UnicodeString::Delete.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    Windows XPOpera

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » poniedziałek, 11 stycznia 2010, 13:02

Żeby było zabawniej metoda data zwraca to samo co c_str, tyle że const, choć sama nie jest const, w przeciwieństwie do c_str. Gdzie tu logika? :shock:
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » poniedziałek, 11 stycznia 2010, 16:22

polymorphism napisał(a):Żeby było zabawniej metoda data zwraca to samo co c_str, tyle że const, choć sama nie jest const, w przeciwieństwie do c_str. Gdzie tu logika? :shock:


Podejrzewam że dodali const gdzie mogli,tzn gdzie ta zmiana nie wpływała by na konieczność zmian w kodzie dla podobnych do tego:

Kod: Zaznacz cały
 
TFileStream *fs = new TFileStream(FileName, fmOpenread |
                                    fmShareDenyNone);
  try
    {
      AnsiString S;
      S.SetLength(fs->Size);
      fs->ReadBuffer(S.c_str(), fs->Size);
    }
  __finally
  {
    delete fs;
  }

Podobnie (SetLength(), .c_str()) można by robić dla WinApi.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    Windows XPOpera

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » poniedziałek, 11 stycznia 2010, 17:19

Problem w tym, że ten const niczego nie zmienia, wnosi jedynie chaos.
Kod: Zaznacz cały
void foo(const AnsiString &str)
{
    str.c_str()[0] = 0;
}

wywołanie c_str dla obiektu stałego jest poprawne, zmiana zawartości str także, pomimo że jest to obiekt stały. Coś tu chyba nie gra...

Z tego co się orientuje, AnsiString/UnicodeString ma wbudowany mechanizm copy-on-write, i pytanie, co będzie zawierał string B:
Kod: Zaznacz cały
AnsiString A,B;
A = "X";
B = A;
A.c_str()[0] = 'Y';
cout << B.c_str(); <--- ???
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » wtorek, 12 stycznia 2010, 01:26

polymorphism napisał(a):wywołanie c_str dla obiektu stałego jest poprawne, zmiana zawartości str także, pomimo że jest to obiekt stały. Coś tu chyba nie gra...


myślę że mogli dać:
const char* c_str() const
char* c_str()

polymorphism napisał(a):Z tego co się orientuje, AnsiString/UnicodeString ma wbudowany mechanizm copy-on-write


A.Unique() powinno pomóc, może dla takich przypadków ta metoda jest dostępne w publicznym interfejsie ;)
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    Windows XPOpera

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » wtorek, 12 stycznia 2010, 11:33

myślę że mogli dać:
const char* c_str() const
char* c_str()

Dokładnie ;)

A.Unique() powinno pomóc, może dla takich przypadków ta metoda jest dostępne w publicznym interfejsie ;)

Czyli B zawiera 'Y'? Jeśli chodzi o Unique, zapewne jest tak jak piszesz, tylko wydaje mi się, że mechanizm copy-on-write powinien być niewidoczny dla użytkownika.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » wtorek, 12 stycznia 2010, 20:03

polymorphism napisał(a):
Czyli B zawiera 'Y'?


Tak jak założyłeś B zawiera "Y". Próbowałem szukać kodów które zapisują do String'a przez .c_str() i niewiele znalazłem. Nie wiem czemu c_str() nie zwraca const * char/const *wchar . Myślę że mogli to dodać ten const przy przechodzeniu na UnicodeString (wtedy i tak trzeba często dostosowywać stary kod).
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    Windows XPOpera

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez mko000 » niedziela, 17 stycznia 2010, 16:14

Ok wszystko pięknie ładnie ale jak próbuje skompilować kod który Cyfrowy Baron podał wyżej wywala mi mnóstwo błędów. Jakie biblioteki należy dodać do tego kodu?
Avatar użytkownika
mko000
Homos antropiczny
Homos antropiczny
 
Posty: 74
Dołączył(a): sobota, 19 grudnia 2009, 00:30
Podziękował : 35
Otrzymał podziękowań: 0
System operacyjny: Windows XP Pro SP2
Kompilator: C++ Builder 2010
    Windows XPChrome

Poprzednia stronaNastępna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 4 gości