Gå til innhold

litt raskere string


Anbefalte innlegg

String(std::string const& s_)
{
char const* t = s_.c_str();
size_t size = strlen(t);
_s = static_cast<char*>(malloc(size));
strncpy(_s, t, size);  
} // constructor

 

raskere å gjøre

 

String(std::string const& s_)
{
size_t size = s_.size();
_s = static_cast<char*>(malloc(size));
strncpy(_s, s_.c_str(), size);  
} // constructor

 

bare sånn siden du ville at den skulle være så himla rask.

 

Skjønner ikke helt hva denne string-klassen skulle være godt for heller, jeg mener, du nullterminerer jo ikke stringen. men det er en annen sak

Endret av saboi
Lenke til kommentar
Videoannonse
Annonse

Takk for tipset. :]

 

Skjønner ikke helt hva denne string-klassen skulle være godt for

Jeg skal lagre siimple tekststrenger i en kø for videresending over sockets (både lokale og ipv4 ..etc.) og pipes, event mmap o.l.. Dette skal skje på en server med masse forbindelser og "ruting" hit-og-dit .. så ting må gå så fort som mulig, og jeg trenger ikke noen av std::string's funksjoner her. Kommer sikkert borti andre steder jeg ikke har bruk for std::string's funksjonalitet etterhvert.

 

du nullterminerer jo ikke stringen.

Ouch .. dét stemmer. (Var som sagt i hui og hast, og trøtt i trynet når jeg skrev dette.). :}

 

Noe slikt blir det vel da:

  String(char const* s_)
 {
 	size_t size = strlen(s_) + 1; // + 1 for terminating '\0'.
 	_s = static_cast<char*>(malloc(size));
 	strncpy(_s, s_, size); // strncpy includes the terminating '\0'.
 } // constructor
 

 String(std::string const& s_)
 {
 	std::string::size_type size = s_.size() + 1; // + 1 for terminating '\0'.
 	_s = static_cast<char*>(malloc(size));
 	strncpy(_s, s_.c_str(), size); // strncpy includes the terminating '\0'.
 } // constructor

 

Maybe legge til en assignment operator også. (Eventuellt sette assign og copy ctr. private ...)

Endret av søppel
Lenke til kommentar

Funderte litt .. og dette ville vel vært en ennå raskere måte å assigne og/eller kopiere på:

...
 String(String const& s_)
 	:_only_owner(true)
 {
 	/*
   size_t size = strlen(s_._s) + 1; // + 1 for terminating '\0'.
   _s = static_cast<char*>(malloc(size));
   strncpy(_s, s_._s, size); // strncpy includes the terminating '\0'.
 	*/
 	const_cast<String&>(s_)._only_owner = false;
 	_s = s_._s;
 } // constructor


 ~String()
 {
 	if(_only_owner)
   free(_s);
 } // destructor

 
 String& operator=(String const& s_)
 {
 	if(_s)
   free(_s);
 	/*
   size_t size = strlen(s_._s) + 1; // + 1 for terminating '\0'.
   _s = static_cast<char*>(malloc(size));
   strncpy(_s, s_._s, size); // strncpy includes the terminating '\0'.
 	*/
 	const_cast<String&>(s_)._only_owner = false;
 	_s = s_._s;
 	return(*this);
 } // operator=
...
private:
 char* _s;
 bool _only_owner;
...

?

 

Edit:

_only_owner blir satt til true i de andre konstruktørene også.

 

Videre, ang. dette med stil, pleier jeg å gjøre følgende:

_bla er lik this.blah liksom .. mens bla_ altid er snakk om parametere..eller "noe annet utenfor". Tror det er det som er "rarest" og det jeg får mest kommentarer/klager på ang. stilen jeg kjører, men det er sånn jeg holder styr på det i hvertfall. :}

 

(postet i hast dette også - mulig jeg har glømt noe *se over*) :}

 

Edit2:

Maybe _only_owner burde hett _last_owner.

 

Edit3:

Fått noen tips .. maybe refcounting er det man ender opp med hvis dette skal fungere i alle tilfeller .. :/

 

Edit4:

Så noe slikt da kanskje:

 

string.hpp:

#include <cstdlib>
#include <string>
#include <string.h>

class String {
public:
 String()
 {
 	construct();
_s = static_cast<char*>(malloc(1));
strncpy(_s, "", 1);
 } // constructor

 
 String(char const* s_)
 {
 	construct();
 	size_t size = strlen(s_) + 1; // + 1 for terminating '\0'.
 	_s = static_cast<char*>(malloc(size));
 	strncpy(_s, s_, size); // strncpy includes the terminating '\0'.
 } // constructor
 
 
 String(char* s_)
 {
 	construct();
 	size_t size = strlen(s_) + 1; // + 1 for terminating '\0'.
 	_s = static_cast<char*>(malloc(size));
 	strncpy(_s, s_, size); // strncpy includes the terminating '\0'.
 } // constructor
 

 String(std::string const& s_)
 {
 	construct();
 	std::string::size_type size = s_.size() + 1; // + 1 for terminating '\0'.
 	_s = static_cast<char*>(malloc(size));
 	strncpy(_s, s_.c_str(), size); // strncpy includes the terminating '\0'.
 } // constructor


 String(String const& s_)
 {
 	_s = s_._s; 
 	_ref_count = s_._ref_count;  	
 	(*_ref_count)++;
 } // constructor


 ~String()
 {
 	if(*_ref_count == 1) {
   destruct();
 	}
 	else
   (*_ref_count)--;
 } // destructor

 
 String& operator=(String const& s_)
 {
 	if(*_ref_count == 1) {
   destruct();
 	}
   else
 	(*_ref_count)--;

 	_s = s_._s;
 	_ref_count = s_._ref_count;  	
 	(*_ref_count)++;
 	return(*this);
 } // operator=


 operator char*()
 {
 	return(_s);
 } // operator char*
 

private:
 char* _s;
 unsigned int* _ref_count;	

 
 void construct() 
 {
 	_ref_count = static_cast<unsigned int*>(malloc(1 * sizeof(unsigned int)));
 	*_ref_count = 1;
 } // construct


 void destruct()
 {
 	free(_s);
 	free(_ref_count);
 } // destruct
}; // String

 

test.cpp:

#include "string.hpp"
#include <iostream>
#include <vector>
#include <time.h>

using namespace std;


void testString(String s, unsigned long steps)
{
if(steps) {
 testString(s, steps - 1);
}
}  // testString


void testSTDString(std::string s, unsigned long steps)
{
if(steps) {
 testSTDString(s, steps - 1);
}
}  // testString


int main()
{

clock_t s;
unsigned long steps = 1000000;

cout << "String-class:" << endl;
s = clock();
testString(String("Dette er en test"), steps);
cout << "CPU time used: " << clock() - s << endl;
cout << endl;

cout << "std::string class:" << endl;
s = clock();
testSTDString(std::string("Dette er en test"), steps);
cout << "CPU time used: " << clock() - s << endl;

return(0);
} // main

 

String-class:

CPU time used: 220000

 

std::string class:

CPU time used: 440000

 

Dobbelt så rask i dette tilfellet, men ved konstruksjon virker den litt tregere enn std::string. hm ..

Endret av søppel
Lenke til kommentar

Tror denne går over til å bli/bruke en eller annen smart-pointer.

 

Jeg får ikke redigert innleggene her inne lenger?

 

Edit:

Jo - denne posten går nå, men ikke den ovenfor. *shrug*

Endret av søppel
Lenke til kommentar

Vil anbefale deg å lese Item 13-16 i "More Exceptional C++" av Herb Sutter. Der viser han eksempler på "lazy optimization" av strenger og problemer det medfører spesielt med tanke på trådsikkerhet (som kanskje er aktuelt siden du skal bruke klassen i forbindelse med sockets).

 

Det avhenger av hvordan strengene brukes, men for min egen del har jeg erfart at det generelt er lite å hente med "lazy strings", blant annet fordi de introduserer synkronisering og kompleksitet.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...