[gelöst] Vector ist wesentlich langsamer als Array?
-
ret=static_cast<double>(_8fak_inv); ret*=_sq_x; ret+=static_cast<double>(_6fak_inv); ret*=_sq_x; ret+=static_cast<double>(_4fak_inv);
Ok,.. also nach der Konstruktion hast Du aber eine fixe anzahl an Schichten und
Neuronen?
-
Hat mir das mit dem operator!= doch keine Ruhe gelasen, der Grund warums bei mir nicht ging war, das #include <string> "gefehlt" hat - string selbst wurde wohl aber über einen anderen include mitgezogen. Beim MSVC wohl nur string, bei gcc und dev++ wohl auch die globale funktion. *Peinlich von mir*
-
Du musst übrigens nicht allen Membervariablen und Funktionen this-> voranstellen, das geht in den meisten Fällen auch ohne.
-
zeusosc schrieb:
@ComputerCarl:
Ok,.. also nach der Konstruktion hast Du aber eine fixe anzahl an Schichten und
Neuronen?Genau! Nach dem Konstruktor sind alle Attribute fest in der Anzahl ihrer Dimensionen.
-
Wenn Dir M[i] Deine Schicht indiziert und M[i][j] Dein Neuron
brauchst Du also "nur" ein zur Initialisierungszeit dynamisches array...Dein Neuron hat welche Parameter?
typedef struct _neuron { double* weight; // gewichte der eingänge LPVOID _ue_func; //zeiger auf eine Gewichtungsfunktion (übertragungsfunktion) LPVOID _outbarrier_func;// Ausgangsschwellenfunktion, also aktivierungsfunktion }
oder sind die Gewichte bei Dir schon mit M[i][j][w] gegeben?
grüße
------
edit:
ahh ok,.. ich sehe es gerade,..
ich bastele mal was
-
Wenn Dir M[i] Deine Schicht indiziert und M[i][j] Dein Neuron
brauchst Du also "nur" ein zur Initialisierungszeit dynamisches array...-> Das sehe ich noch nicht, aber das muss nichts heißen.
Also kurz ich weiß nicht, wie ich die eine Dimension reduzieren kann.
Ich mein, ich könnte mir die Anzahl der Schichten mit der Anzahl der Neuronen
zwischen-speichern und somit die "Referenzierung" auf ein Index selber zusammen basteln, aber ich weiß nicht ob das gemeint ist.Dein Neuron hat welche Parameter?
typedef struct _neuron { double* weight; // gewichte der eingänge LPVOID _ue_func; //zeiger auf eine Gewichtungsfunktion (übertragungsfunktion) LPVOID _outbarrier_func;// Ausgangsschwellenfunktion, also aktivierungsfunktion }
oder sind die Gewichte bei Dir schon mit M[i][j][w] gegeben?
Na ja nicht ganz... ein Neuron hat soviele Gewichte wie Neuronen in der vorhergehenden Schicht. Also jede Verbindung von Neuron j aus Schicht i
führt zu Neuron k in Schicht i+1. Die Gewichte sind in w[i][j][k] gespeichert.
wTx in activate liefert mir somit die Aktivierung durch die Vorgänger-Neuronen und der tanh(beta * (wTx - bias)) bestimmt somit die Weiterleitung in die Nächste Schicht. Diese wird in M[i+1][k] gespeichert.Welche Funktionen LPVOID ... übernehmen sollen kann ich erahnen, sehe aber nicht die Notwendigkeit.
-
Ich werde jetzt bis morgen früh erst mal das Feld räumen.
Sollten noch Fragen an mich kommen also nicht warten. Ich
werde heut nicht mehr antworten.
Um aber vielleicht ein besseres Bild von solch einem Netz
zu schaffen wollte ich nur ebenmal eine graphische Darstellung
posten. Auf dieser Seite wäre solch ein Netz, was eigentlich
in meinem Code implementiert wurde. Text der Seite hab ich nicht
mehr gelesen nur die Darstellung ist denke ich hilfreich.Hier das Bild isoliert:
http://193.25.32.158/fb2/prof/skrueger/images/stories/neuronetze/rendite.gif
-
Ach schade,.. bin gerade fertig geworden,...
Naja vlt können die anderen das ja mal auseinander nehmen:
//####################################################################################################### // Base Array class deklaration //####################################################################################################### template<typename T> class _base_array { private: T *_ptr; unsigned int size; bool _malloc(unsigned int Size); void _free(void); void _clear_all(void); public: _base_array(); _base_array(unsigned int Size); ~_base_array(); void reserve(unsigned int Size); // just call it ONCE unsigned int _nr_of_elements(void); // returns the absolute number of accessable elements unsigned int _size(void); //returns the size of array in Bytes T & operator[](int Index); }; //####################################################################################################### // Base Array class definitions //####################################################################################################### template<typename T> bool _base_array<T>::_malloc(unsigned int Size) { bool bRet=false; if( this->_ptr ) return bRet; this->_ptr=reinterpret_cast<T*>(malloc(sizeof(T)*Size)); if( !this->_ptr ) { this->size=0; return bRet; }; this->size=Size; for(int i=0; i<Size; i++) (*(this->_ptr+i))=T(); return !bRet; }; template<typename T> void _base_array<T>::_free() { if(!this->_ptr) { this->size=0; return; }; free(reinterpret_cast<void*>(this->_ptr)); this->_ptr=reinterpret_cast<T*>(0); this->size=0; }; template<typename T> void _base_array<T>::reserve(unsigned int Size) { this->_malloc(Size); }; template<typename T> void _base_array<T>::_clear_all() { this->size=0; this->_ptr=reinterpret_cast<T*>(0); }; template<typename T> _base_array<T>::~_base_array() { this->_free(); this->_clear_all(); }; template<typename T> _base_array<T>::_base_array() { this->_clear_all(); }; template<typename T> _base_array<T>::_base_array(unsigned int Size) { this->_clear_all(); this->_malloc(Size); }; template<typename T> unsigned int _base_array<T>::_nr_of_elements() { return this->size; }; template<typename T> unsigned int _base_array<T>::_size() { return this->size*sizeof(T); }; template<typename T> T & _base_array<T>::operator [](int Index) { if((Index <0 )|| (static_cast<unsigned int>(Index) > this->size-1)) return *(new T()); return *(this->_ptr +Index); }; //####################################################################################################### typedef _base_array<int> _bai; typedef _base_array<_bai> _cai; typedef _base_array<_cai> _dai; //####################################################################################################### int _tmain(int argc, _TCHAR* argv[]) { _bai b(12); _cai c(12); _dai d; d.reserve(12); for(int i=0; i<12; i++) { b[i]=i; c[i].reserve(12); d[i].reserve(12); }; for(int x=0; x<12; x++) { for(int y=0; y<12; y++) { d[x][y].reserve(12); } }; for(int x=0; x<12; x++) { for(int y=0; y<12; y++) { for(int z=0; z<12; z++) { d[x][y][z]=x+y*12+z*12*12; //weiß nicht ob die rechnung richtig ist,... } } }; __debugbreak(); return 0; }
grüße
-
Warum benennst du deine Klassen so grausam mit dem _ als Präfix?
-
Ja,..
Warum machen andere das nicht?
_Weil _man _die _Freiheit _hat das zu tun und zu lassen was man will,..
... und ausserdem ließt und schreibt sich das für mich leichter,...
Ansonste fällt mir nicht mehr ein..
-
zeusosc schrieb:
Warum machen andere das nicht?
Weil alle Bezeichner vom Standard reserviert sind, die mit einem Unterstrich starten auf welchen ein Großbuchstabe folgt. Ok, deine Bezeichner sind zwar nicht nicht standardkonform, aber doch mehr als unüblich. Vor allem für Klassen und Funktionen. Da sind insgesamt noch so einige Hauer drin, aber da will ich jetzt nicht drauf eingehen, irgendjemand nimmt sich bestimmt die Zeit.
-
Ok,..
soweit ich weiss folgt bei mir auf den Unterstrich aber ein
kleiner Buchstabe bzw. eine Zahl.
Daher unterscheidet sich das von dem reservierten,..Hauerdrinn?
jetzt bin ich neugierig,... auslernen will ich ja auch nicht,...
-
wow... Danke!
Ich muss mich da erstmal reinlesen. Diesen "erfahrenen"
Programmierstil bin ich noch nicht gewöhnt. Aber ich
glaube zu sehen was gemeint ist. Werde einfach meinen
Code überarbeiten (angelehnt an das gepostete).Vielen Dank an alle die Tipps gegeben haben. Ich
werde jetzt einfach mal das Thema als gelöst markieren.
-
zeusosc schrieb:
Hauerdrinn?
jetzt bin ich neugierig,... auslernen will ich ja auch nicht,...
Keine Sorge, "Auslernen" wirst du so schnell sicher nicht.
- Die sehr hässlichen _ am Anfang wurden ja schon erwähnt.
- Ein komisches selbst gebasteltes malloc statt new[]?
- Cast nach void*?
- Cast von 0 nach T*?
- Das ständige this-> irritiert total.
- Nicht richtig eingerückt.
- Komische und unnötige ; hinter if() und hinter Funktionen, die den Lesefluss total behindern.
- Index von operator [] nicht unsigned.Und wo bitte ist bei dir überhaupt der Vorteil zu std::vector? Im Speicher liegt doch immer noch alles kreuz und quer, oder habe ich in dem WirrWarr jetzt den Super-Trick übersehen?
-
Was du noch machen kannst, wenn die Dimensionen zwar fest aber erst zur Laufzeit bekannt sind, ist, dir eine Klasse zu bauen, die Größenangaben zu den Dimensionen im Konstruktor nimmt, und dann Zugriff über operator () mit drei Indexvariablen auf einmal gibt. (Intern nutzt du einfach einen std::vector und reservierst sx * sy * sz Elemente am Stück).
int main() { unsigned sx, sy, sz; // Werte einlesen DeineKlasse<float> mat(sx, sy, sz); mat(5, 7, 3) = 77; // Zugriff }
Ob das viel schneller ist weiß ich nicht, da du den Index halt auch zur Laufzeit ausrechnen musst. (Das sind halt Multiplikationen, wie man die Dimensionen runterrechnet weißt du?)
Aber ich denke mal einen Versuch ist es wert.
-
cooky451 schrieb:
Ob das viel schneller ist weiß ich nicht, da du den Index halt auch zur Laufzeit ausrechnen musst. (Das sind halt Multiplikationen, wie man die Dimensionen runterrechnet weißt du?)
Aber ich denke mal einen Versuch ist es wert.Glaub mir, das ist VIEL
schneller.
Was ist denn Arraydereferenzierung? Additionen und Multiplikationen. Es ist daher so schnell wie ein zusammenhängendes Array mit dem Komfort eines Containers.
-
SeppJ schrieb:
Was ist denn Arraydereferenzierung? Additionen und Multiplikationen. Es ist daher so schnell wie ein zusammenhängendes Array mit dem Komfort eines Containers.
Äh ja, stimmt, der Index muss ja auch bei statischen Arrays errechnet werden, irgendwie hatte ich da einen Denkfehler. Super, dann dürfte das ja die Lösung sein.
-
zeusosc schrieb:
soweit ich weiss folgt bei mir auf den Unterstrich aber ein
kleiner Buchstabe bzw. eine Zahl.17.6.4.3.2: Global names, zweiter Punkt:
Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
Deine Klasse liegt im global namespace, deshalb ist ALLES was mit einem einzigen Unterstrich beginnt, ebenso der Implementierung vorbehalten und sollte vom User nicht verwendet werden.
-
cooky451 schrieb:
zeusosc schrieb:
Hauerdrinn?
jetzt bin ich neugierig,... auslernen will ich ja auch nicht,...
Keine Sorge, "Auslernen" wirst du so schnell sicher nicht.
- Die sehr hässlichen _ am Anfang wurden ja schon erwähnt.
- Ein komisches selbst gebasteltes malloc statt new[]?
- Cast nach void*?
- Cast von 0 nach T*?
- Das ständige this-> irritiert total.
- Nicht richtig eingerückt.
- Komische und unnötige ; hinter if() und hinter Funktionen, die den Lesefluss total behindern.
- Index von operator [] nicht unsigned.Und wo bitte ist bei dir überhaupt der Vorteil zu std::vector? Im Speicher liegt doch immer noch alles kreuz und quer, oder habe ich in dem WirrWarr jetzt den Super-Trick übersehen?
Also, trick ist da keiner.
Die Anforderung war (so wie ich das sah):
Schreibe ein zur initialisierungszeit dynamisches Array auf
das man mit [][][] zugreifen kann, und recht fix ist.STL vectoren springen häufig durch verschiedene Unterfunktionen,
die die Länge prüfen, ob der Zeiger richtig ist und und und,..
hier wird alloziiert und über maximal zwei ptrs beim zugriff
dereferenziert (und auf das dritte dan referenziert)...
sollte also relativ flink laufen,..Jetzt mal vom underscore abgesehen:
* Zum new: ich vermeide es wo ich kann! (hier nutze ich es exakt 1x)
Wird der new operator nicht über den source definiert, so findet
eine (Compiler spezifische) Ersetzung statt, die ich erst zur Laufzeit
sehe. Das will ich nicht!* Cast von 0 nach T* : 0 ist kein Typ.
Sind verschiedene konvertierungsvorschrifften vorhanden,
wird die erste passende vom Compiler genommen. (Meistens basistypen).
Ich will das der Compiler "explizit" 0 als T* behandelt.* Cast nach void*: sehe ich jetzt nicht,.. wo?
* Index operator [] nicht unsigned: Ja,.. kann man so und so sehen,
"ist übergebene uint > size dann gib referenz" wäre hier wohl
bessere wahl gewesen, da hast du recht...* this-> bleibt definitiv !!! es ist ein unterschied ob ich eine
Methode der Instanz aufrufe oder eine gleichnamige Funktion aus
dem gleichen Namensraum, geschweige denn Member.
Da der Compiler das so oder so die addy's der Member aus der
Referenzierung des this holt (in asm schön sichtbar), dann
kann ich es auch gleich richtig machen. Ausserdem ist dann
IMMER klar, WANN ich eine Methode oder Member innerhalb einer
Methode aufrufe,...
(Macht sich besonders bemerkbar wenn intellisense spinnt)* Einrückung: hä? wie was? wo?
Es gibt ja mal wohl mehrere Varianten von einrückungen...* ";" ?? Meines wissens hat nach jeder abgeschlossenen Anweisung ein ";"
zu folgen. Auch wenn manchen Compilern das wurscht ist....Also bis auf die underscores und dem uint (danke, ja da haste ja recht)
sehe ich jetzt nicht viele hauerdrinn,...@Cookie457:
Ja, hatte ich auch zuerst überlegt,... dann dachte ich, bevor er sich
mit "suchen und ersetzen" menüpunkt anlegt um die [i][j][k] durch
(i,j,k) zu ersetzen, gleich n template mit variabler dim anzahl
basteln. Er nutzt ja mehrere 1d 2d und 3d arrays.,...grüße
-
zeusosc schrieb:
STL vectoren springen häufig durch verschiedene Unterfunktionen,
die die Länge prüfen, ob der Zeiger richtig ist und und und,..Wenn du mit "häufig" meinst "im Debugmodus", dann kann man das so stehen lassen.