Wie Pippl ja bereits geschrieben hat ist HTL-Abschluss bei weitem kein Studium. Man hat einen Abschluss der einen berechtigt weiter zu studieren an zb einer Uni/FH. Je nach Richtung der HTL und danach gewähltem Studium ist es möglich sich 1-2 Semester anrechnen zu lassen.
Wenn ich das jetzt mit deutschen Verhältnissen vergleichen müsste dann würde ich sagen dass ein HTL-Abschluss + anschließendem Ingeneurstitel ungefähr dem Stand eines Fachinformatikers entspricht.
Ich teste das morgen auf der Arbeit. Hab grad keinen MAC zur Hand.
Aber soweit ich mich erinnern kann musste ich keine Leerzeilen bzw Kommentare entfernen.
EDIT: Ich habe das Script eben getestet und das mit den Leerzeilen und Kommentaren funktioniert problemlos wenn ich eben npsvosx.exe durch meine ersetze.
Das Einzige was mir aufgefallen ist bzw ich geändert habe:
EXE_PATH="$DIR\npsvosx.exe"
Versuch mal einen Slash(/) anstatt des Backslash zu verwenden.
Auf welchem OSX hast du das getestet?
Hast du das Script vorher auch auf executeable gesetzt? chmod +x
Also ich habe vor einiger Zeit selbst ein erweitertes Shell-Script, das uA gleich das Mono-FW lädt und installiert, auf Basis dieses Posts gebastelt.
Starte das Shell-Script mal im Terminal und poste die Ausgabe bzw poste mal dein Shell-Script.
So ich habe mich jetzt mal eingehend mit dem Problem beschäftigt und etliche Tests durchgeführt.
Der csv Reader ist nicht das Problem. Das Einlesen dauert ca. 3-4 Min.
Danach habe ich versucht eben nicht nach jeder gelesenen Zeile eine Anfrage an die DB zu senden sondern eben alles einzulesen und dann nur 1 Anfrage zu stellen. In der csv stehen ca 40000 verschiedene Tracks. Dies brachte auch nicht so wirklich einen Zeitsprung. Das wurde dadurch nur 30 Minuten schneller.
Als letzte Lösung habe ich dann versucht mal nHibernate ganz wegzulassen und direkt ein DataTable zu verwenden. Bis das DataTable mit den 40000 Zeilen/Tracks geladen ist dauert es ca 30 sec.
Heureka ich dachte jetzt hab ichs. Auslesen der csv in ein DataTable 3 Min + laden der 40000 Tracks in eine DataTable weitere 30 sec. Einfach nur die fehlenden Infos aus der Datatable holen und in der anderen ergänzen. Mittels Linq ja auch einfach und schnell erledigt. Das sollte nicht lange dauern und definitiv etwas bringen.
Dann auch gleich getestet und es kam die böse Überraschung. Das ganze dauert immer noch 6 Stunden. Somit hab ich fast nix gewonnen.
Nur wie kann das sein? Ich hab beide DataTable im Speicher und durchlaufe die mit 2 verschachtelte foreach Schleifen.
Hier der Code: Bis der durchgelaufen ist dauert es eben 6 Stunden.
dtTracks ist mein DataTable mit den 40000 Tracks/Zeilen.
dtSales ist das riesige Datatable mit den den Werten aus der csv.
Was kann ich noch machen? Ich bin grad mit meinem Latein am Ende und für weitere Ideen mehr als dankbar.
Parallel.Foreach würde mir noch einfallen. Nur kann ich darauf nicht zugreifen, da ich aufs 3.5er FW zugreifen muss. Außerdem kann ich mir net vorstellen dass ich damit von 6 Stunden auf 1 runter komme.
Super, vielen Dank.
Das bringt mich schon ein ganzes Stück weiter.
Noch ein wenig zum Hintergrund.
Wie gesagt handelt es sich hierbei um Verkaufszahlen. Wir bekommen derzeit ca 50 verschiedene csv/txt Dateien in unterschiedlichen Formaten(andere Header, Trennzeichen, etc) und einigen Eigenheiten. Nicht alle sind immer well-formed. Darum auch der Reader und nicht nur ein einfacher StreamReader.
Der Reader liest jetzt eben abhängig vom File die jeweiligen Werte, die benötigt werden, raus(Dazu unten mehr). Als Identifier dient hier der EAN/ISRC(falls sich jemand ein wenig im Msuic-Business auskennt) und anhand dessen Stelle ich die Abfrage via nHibernate an die DB um das Album zu erhalten, denn anhand der Trackanzahl und Spieldauer der jeweiligen Tracks werden dann eben die Berechnungen durchgeführt.
Sprich hier brauch ich sowieso immer gleich die Tracks dazu, also eager loading. 15mio Anfragen kommen hier nicht zustande, da viele Zeilen im CSV ident sind.
Also in der csv steht in Zeile 1: Album A hat sich in Deutschland 100 mal verkauft => Anfrage via nHibernate an die DB um welches Album es sich handelt
Zeile 2: Album A hat sich in Österreich 50 mal verkauft => keine Anfrage an DB, da ich das Album bereits in meinem Dictionary hab.
Zeile 3: Album B ... => Anfrage an DB
Unsere Tabelle mit den Alben/Tracks umfasst ca 500.000/5.000.000. Somit können derzeit nur max 500.000 Anfrage während des Auslens der CSV an die DB gestellt werden. Wie gesagt wächst die natürlich auch kontinuierlich. Darum will/wollte ich die nicht einfach vorab laden sondern eben nur pro Zeile bzw die Alben/ Tracks die auch verkauft wurden. Sonst hätte ich 5,5 Mio Objekte im Speicher und verkauft wurden dann aber nur 1000 unterschiedliche.
Hier werde ich mich mal mit dem nhibernate Profile einklinken und gucken was da wirklich so abgeht.
Caching
Das mit dem Clear passiert noch nicht. Das werde ich auch mal testen und etwas rumspielen.
Cascade
Mapping werde ich auch nochmals prüfen. Mit nHibernate lade ich eben nur die Informationen zu den jeweiligen Tracks/Alben. Ich führe nur Selects keine Insert/Update/Delete aus.
Wie oben erwähnt brauch ich aber sowieso alle Tracks des Albums.
Die Daten werden in eine andere Tabelle geschrieben.
Mein Datatable hat eigentlich nur folgende Spalten:
EAN: der wird aus der csv
ISRC: ebenfalls csv
Stückzahl: ebenfalls csv
AlbumTitel: kommt eben via nhibernate-Abfrage
TrackTitel: ebenfalls nhibernate
Label: ebenfalls nhibernate
und dann eben noch 3 double-Spalten: das sind die Werte die ich berechne
Deswegen verwende ich eben ein Datatable das ich zur Hälfte mit Daten aus der CSV und zur anderen Hälfte mit den Album- und Track-Informationen und meinen Berechnungen befülle.
Das schien mir in meinem Fall am performantesten. Spricht etwas gegen dieses Vorgehen?
Ich werde auch mal nen Vergleich zwischen meinem CSV-Reader und dem FileHelpers machen.
Werde in den nächsten Tage etliches rumtesten und versuchen nen genaueren Überblick zu geben bzw Ergebnisse zu posten.
Also ich wäre definitiv an einem Artikel zu Optimierungen von nHibernate.
PS: Heute hab ich mal nur getestet wie schnelle es der Import-Assistent aus dem SQl Management Studio schafft die 900MB und 15Mio Zeilen in die Tabelle zu packen. Das war in ca 3-4 Minuten erledigt. Wie gesagt nur die reinen Daten aus dem CSV. Keine zusätzlichen Infos und Berechnungen.
Leider hat sich mittlerweile beim Auslesen einer riseigen csv Datei und anschließendem speichern in die DB ein Performanceproblem ergeben.
Die csv ist derzeit ca 1GB groß mit ca 15.000.000 Zeilen und wird vermutlich auch in nächster Zeit noch wachsen.
Ein wenig zum Hintergrund wie und was derzeit passiert.
In diesem CSV stehen pro Monat die Verkäufe von Alben bzw Tracks nach Länder aufgeschlüsselt.
1.)Die Csv wird derzeit mit folgendem Reader zeilenweise ausgelesen.
2.)Dann wird eine Anfrage an DB geschickt und das Album bzw der Track geladen, der diesem Verkauf entspricht. Dies erfolgt via nHibernate und es wird immer das gesamte Album inkl Tracks geladen, da die später für Berechnungen gebraucht werden.
3.) das Ergebnis der DB Abfrage wird in einem Dictionary gespeichert. Somit wird für alle weiteren Zeilen der CSV geprüft ob das Album/Track schon mal geladen wurde und falls ja eben keine Anfrage an die DB geschickt.
4.) Nun werden eben Berechungen(nur ein paar Subtraktionen und Multiplikationen) mit den Verkäufen und den Album/Tracks gemacht und danach eine Zeile in eine DataTable geschrieben.
5.) Diese Datatable wird dann mittels SqlBulkCopy in eine Tabelle geschrieben. Das Ganze muss innerhalb einer Transaction laufen und deswegen verwende ich eben UseInternalTransaction und BatchSize ist 0.
Bis das Ganze durchgelaufen ist vergehen ca 7 - 9 Stunden. Wobei die Schritte 1-4 ca zwei Drittel der Zeit in Anspruch nehmen.
Jetzt kam die Anforderung, dass dies(csv auslesen und in db speichern) schneller gehen muss. Das muss in 20 Minuten erledigt sein. Persönlich halte ich das für mehr als utopisch aber evtl lässt sich ja doch was machen.
Was mir noch aufgefallen ist, dass das abschließende Commit so lange dauert wie das schreiben in die DB. Ich lasse mich mittels NotifyAfter alle 10% vom Fortsschritt informieren. Dieser steht nach 1 - 1,5 Stunden bei der Anzahl der Rows und das abschließende Commit verbraucht wieder so ca 1 Stunde.
So und nun zu meinen Fragen:
Wo bzw wie könnte man noch optimieren?
Ich habe bisher noch nie mit so riesigen Datenmengen gearbeitet. Evtl ist die Dauer ja normal?
Ich könnte vorher bereits alle Alben/Tracks aus der DB laden. Somit enfällt dann der DB-Zugriff während des csv-auslesens. Das würde evtl etwas bringen nur werden die Alben/Tracks täglich mehr und irgendwann entsteht vermutlich hier der Bottleneck.
Die Csv in kleinere Portionen aufteilen und jeweils in die DB schreiben. Nur muss ich mich dann ja selbst darum kümmern falls zb beim letzten Batch was schief läuft, dass alle vorherigen auch gelöscht werden.
mdProjectTimer dürfte so ziemlich das sein was du suchst. Du kannst hier deine Projekte verwalten/anlegen und dann einfach mittels Mausklick wechseln und am Ende siehst du dann welches Project etc wie viel Zeit in Anspruch genommen hat.
Sry für Offtopic. Ja Regex sind ein echt mächtiges Werkzeug. Ich hab leider auch viel zu spät angefangen Sie zu nutzen.
Aber dazu fällt mir noch ein Jamie Zawinski Zitat ein:
Zitat
Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.
Ich bin einfach nicht auf die Idee gekommen den Wert + die Anzahl der nachfolgenden Leerzeichen für den einzufügenden Text zu ersetzen.
Also so wie in dem Bsp von DerKleineTomy.
Somit hab ich jetzt eine allgemein gültige Lösung. Ich habe nämlich verschiedene Frames bzw Templates. So wie BerndFfm das gezeigt hat hätte ich dann für jedes Template ne eigene Behandlung machen müssen.
Vielen Dank, also so einfach kanns gehen.
Ich glaub ich steh grad am Schlauch. Wie soll mir das helfen?
da müsste ich ja wissen wie viele Zeichen es bis zum Rand sind und womit soll ich den string auffüllen? Es verschiebt mir ja dann trotzdem wieder den rechten Rand.
Hi
Also ich habe eine vorgegebene txt-Datei und in diese soll ich Werte aus einige TextBoxen schreiben.
An sich keine Problem, dachte ich mir. Machst du dir einfach ein paar Placeholder rein und dann mittels Replace die Werte ersetzen. Nur so einfach ist das leider nicht, da es mir dann das Layout der txt-Datei zerstört.
Wenn ich da jetzt die Werte einfüge verrutscht mir natürlich rechts der ganze Rand.
Kennt ihr evtl einen Weg wie ich das anstellen könnte ohne das es das Layout zerstört? Mir will da grad nicht wirklich ne zündende Idee kommen.
Ich verwende nHibernate in Kombination mit Fluent nHibernate. Damit geht das ganze eigentlich ratz-fatz.
Und die Config für nHibernate ist ja auch schnell erledigt. Dazu gibts auf der Homepage ein Tutorial.
Kommt ein OR-Mapper(zb nHibernate) in Frage? Da stellst du es in der Konfig ein welcher Dialekt verwendet wird und den Rest übernimmt nHibernate für dich.
Wäre es nicht am einfachsten den Task im Kontext des Benutzers laufen zu lassen der auf die Freigabe zugriff hat? Und auf diese eben nicht über das Netzlaufwerk zuzugreifen sondern eben über den UNC-Pfad.
Ich habe in meinem Projekt laut Resharper 2 Error und zwar meckert er bei BeginInvoke bzw EndInvoke an dass:
Fehler
Argument is 'out' while Parameter is declared as 'value'
Das ganze sieht folgendermaßen aus:
der Delegate:
private delegate int Foo(out string name);
Der Aufruf:
string s;
Foo f = Bar;
IAsyncResult ia = f.BeginInvoke(out s, null, null);
int i = f.EndInvoke(out s, ia);
Bei dem besagten out s kommt eben der Error von Resharper. Wenn ich jetzt sage Correct argument kind, dann lässt er das out weg. Dann kompiliert es nicht mehr was ja auch klar ist, da dass Argument mit out übergeben werden muss.
Nur was genau is das jetzt das Problem bzw was meckert Resharper hier an. Ist das ein Fehler oder ein Bug im Resharper?
Evtl is es ja auch noch zu Früh und ich üebrseh da ja etwas.