armin pfaeffle
temporäre website…
temporäre website…
Jul 6th
Ich bin (mal wieder) auf Herrn Pispers gestoßen, habe mir gestern abend eine Stunde Zeit genommen und auf Youtube Bis neulich gelauscht (alle Videos weiter unten). Es ist an sich sehr amüsant die behandelten Themen anzuhören, aber irgendwie auch beängstigend, da sehr viel Wahres hinter seinen Aussagen steckt.
Hier noch ein sehr interessantes Zitat, welches mit persönlich sehr gefällt: »Die Erfinder der Endlösung sind doch keine Kleinwagenfahrer!«
Aber hört selbst:
Jun 16th
First of all RTTI is a very nice feature I think. You can do a lot of funny things especially when you combine this technique with Generics. But there is a problem I’m not very glad about: the speed is not that good, so I had to change some things in my O/R mapping class. I do not want to explain what I’m working on because my intention of this post is to write down some words about my experiences with this RTTI feature and the speed.
At the moment I have a test application which does the following: it has one class TTest which has two properties, PropA: String and PropB: Integer. I create one instance of this class and set the property in a loop which starts at 100000. The setter call on the one side is the direct setter method and on the other the SetValue() method of the RTTI class TRttiProperty. These are my results; the last two columns are denoted in milliseconds:
| loop count | simple setter | RTTI SetValue() |
|---|---|---|
| 100000 | 0 | 359 |
| 600000 | 15 | 2169 |
| 1100000 | 15 | 4025 |
| 1600000 | 31 | 5772 |
| 2100000 | 16 | 7566 |
| 2600000 | 31 | 9360 |
| 3100000 | 47 | 11201 |
| 3600000 | 47 | 13041 |
| 4100000 | 47 | 14852 |
| 4600000 | 62 | 16567 |
| 5100000 | 63 | 18345 |
As you can see this shows that a call of the SetValue() method is really slow against directly setting a property. So it is not advising that you are using too much of SetValue() like I did ;) I know that there is a lot of magic behind this method and TValue is very powerful but i haven’t believed that there is such a huge difference. In my case now I’m using a mixture of direct setting and getting properties and the usage of the RTTI SetValue/GetValue.
Before some minutes I had a beautiful idea how to improve the speed of setting values via RTTI. Imagine you have an index over the properties (e.g. THashedStringList in unit IniFiles) so that you can find very fast a pointer of the property setter method (okay, you could do this every time via a loop… but that’s stupid). When you want to set a value to a property you only have to get the associated pointer to the setter method (look-up in index), “create” a TMethod instance, set method and object pointer in the TMethod instance and call it. Yeah, it could be so easy, but it is not so easy. Think about properties which doesn’t have a setter method or are not writeable. What about the data type!? TMethod does only support pointers, and so on…
Because there are some traps there are already implementations of this functionality. Look through the code of TypInfo.pas, there you can find methods for nearly all data types which already implements my idea ;) Some examples are SetStrProp(), SetOrdProp() (for integers), SetObjectProp() (for classes), and so on. Here some new Results comparing the three told possibilities (now I used TStopWatch in Diagnostics.pas instead of GetTickCount() method for measure time):
| loop count | simple setter | RTTI SetValue() | TypInfo methods |
|---|---|---|---|
| 100000 | 1 | 349 | 52 |
| 600000 | 6 | 2088 | 313 |
| 1100000 | 12 | 3813 | 571 |
| 1600000 | 18 | 5594 | 834 |
| 2100000 | 24 | 7281 | 1096 |
| 2600000 | 30 | 9047 | 1357 |
| 3100000 | 36 | 10787 | 1617 |
| 3600000 | 42 | 12549 | 1888 |
| 4100000 | 48 | 14303 | 2146 |
| 4600000 | 53 | 15980 | 2436 |
| 5100000 | 60 | 17783 | 2659 |
How you can see the usage of the setter methods in TypInfo.pas is much better than the SetValue() method of the TRttiProperty class. But when you want to use this solution you have to set the properties you want to set via RTTI published and enable the RTTI feature via {$M+} (set this before the corresponding class). You can easily do this with you own classes but what about others?
I have found a way combining the old (TypInfo.pas) and the new (Rtti.pas) version of RTTI to improve speed about 90% comparing the normal setter method usage told above (i mean using the methods which expects a string as property name and not a pointer to PPropInfo). Here some code:
// get references to properties
p1 := T.GetProperty('PropA');
p2 := T.GetProperty('PropB');
// get pointers to PPropInfo of properties
pi1 := TRttiInstanceProperty(p1).PropInfo;
pi2 := TRttiInstanceProperty(p2).PropInfo;
// run benchmark...
for i := 0 to counter do
begin
SetStrProp(obj, pi1, 'User');
SetOrdProp(obj, pi2, 100000);
end;
The trick is not to use the propertyname in SetStrProp() or SetOrdProp() because these methods has an internal loop searching for the PPropInfo of the given property (yes, there als also some other stuff…). So i came to this results:
| loop count | simple setter | RTTI SetValue() | TypInfo methods | Combined methods (code above) |
|---|---|---|---|---|
| 100000 | 1 | 349 | 52 | 4 |
| 600000 | 6 | 2088 | 313 | 26 |
| 1100000 | 12 | 3813 | 571 | 48 |
| 1600000 | 18 | 5594 | 834 | 70 |
| 2100000 | 24 | 7281 | 1096 | 92 |
| 2600000 | 30 | 9047 | 1357 | 114 |
| 3100000 | 36 | 10787 | 1617 | 136 |
| 3600000 | 42 | 12549 | 1888 | 159 |
| 4100000 | 48 | 14303 | 2146 | 181 |
| 4600000 | 53 | 15980 | 2436 | 203 |
| 5100000 | 60 | 17783 | 2659 | 224 |
Now i will use RTTI setter methods again but in my way :)
Here you can download my current Delphi project with which i created these results. I think that it will compile only in Delphi 2010 because if the usage of Rtti.pas and Diagnostics.pas.
Jun 2nd
Ich bin neulich eher durch Zufall auf ein paar Editor-Themes für Netbeans und andere Editoren/IDEs gestoßen und hab mich gewundert, dass es sowas für die Delphi IDE nicht gibt. Ich habe mich heute daher mal daran gemacht sowas für die Delphi IDE der Version 2010 zu machen. In der Zwischenzeit ist das Theme sogar für die Delphi Version 7 bis 2010 verfügbar. Man kann sowas zwar über den Options-Editor der IDE tätigen, allerdings ist das sehr unbequem und umständlich, wie ich finde.
Ein alternativer Weg führt über die Windows-Registry, da man da ein wenig mehr Übersicht hat und schneller einzelne Punkt ändern kann. Was mich dabei aber immer noch gestört hat, ist diese blöde Farbangabe, wie man diese in Delphi auch tätigen muss. Wenn ich mal viel Zeit und Muse dann schreibe ich mal ein Programm über welches man diese Sachen ändern kann.
Hier findet ihr jedenfalls mein erstes Theme – in so fern man das so nennen will.
Hier noch der Download — in jedem Archiv befinden sich die passenden Registry-Einträge für Version 7 bis 2010:
Original Theme (kann über den Optionen-Dialog der IDE auch wieder zurückgesetzt werden)
Leider hat sich ein Fehler eingeschlichen, den ich gerade behoben habe. Und zwar wurde die aktuelle Zeile nicht mit den normalen Farben des Syntax-Highlighting versehen, sondern der komplette Text in dieser Zeile weiß dargestellt. In der aktuellen Version ist dieser Umstand nun behoben.
Habe gerade das Theme für D2009 umgeschrieben, d.h. eigentlich nur aus 7.0 eine 6.0 gemacht :)
Nun wurde das Archiv so erweitert, dass es ab Delphi Version 7 bis 2010 alle Registry-Einträge enthält.
Apr 3rd
Da ich zurzeit wieder einmal eine Business-Anwendung für einen größeren Konzern schreibe und erneut vor dem Problem stehe, wie ich dem Benutzer die Daten präsentiere. Im Allgemeinen kann man mit einer Tabellen-Struktur nichts falsch machen, in so fern die zu zeigenden Daten gleich wichtig sind, aber das gelbe vom Ei ist es dann nun doch nicht, wie ich finde. Jedenfalls sitze ich im Moment schon seit über 2 Stunden über neueren Konzepten, die allerdings nicht unbedingt Praxistauglich sind. Zudem finde ich immer wieder mehr Argumente für eine Tabelle – im Folgenden eine kleine Liste der wichtigsten Argumente – als für ein anderes Konzept.
Versucht man diese Punkte auf ein anderes Konzept zu projizieren, so gelingt dies meist nur bei einem oder zweien, wobei der Aufwand der Implementierung eigentlich immer höher ist. Somit bin ich zum Schluss gekommen, dass ich die Tabelle beibehalte, allerdings mit den folgenden Features ausstatte, die das Arbeiten mit dieser erleichtern sollen.
Darunter zählt zum einen die Filter-Funktion, die sich auf alle (dargestellten) Informationen auswirkt, d.h. wenn mindestens eine Information dem Filter entspricht ist dies ein Treffer. Hier hatte ich noch die Idee, dass die Auswirkung des Filters auf zwei Arten dargestellt werden kann: zum einen kann man die Daten ausblenden, die nicht dem Filter entsprechen, sodass der Nutzer nur noch diese vor sich hat, nach denen er auch gesucht (wobei ich den Begriff Filter von Suche abgrenzen will, da eine Suche wesentlich komplexer ist) hat. Alternativ kann man die Treffer highlighten oder die Nicht-Treffer ausgrauen.
Daneben wäre es sinnvoll eine Gruppierung einzuführen, wie man diese z.B. von Microsoft Outlook oder Mozilla Thunderbird her kennt. Man erleichtert dem Benutzer die manuelle Suche, da er nun nicht mehr über evtl. mehrere hunderte Datensätze fliegen muss, sondern nur noch wenige Gruppen ansehen muss. Des Weiteren steigert das Auf- und Zuklappen von Gruppen die Übersichtlichkeit.
Verknüpfungen zwischen Datensätzen sollten ersichtlich sein, ebenso, soweit es sinnvoll ist, auch direkt einsehbar. An dieser Stelle gibts es mehrere Möglichkeiten dies zu gestalten, wobei ich nur zwei dieser erläutern will. Eine Idee ist es, durch ein [+] (oder ein vergleichbares Symbol) die verknüpften Datensätze unter dem aktuellen Datensatz einzublenden – man klappt die Unterebene auf. Bei dieser Technik stellt sich allerdings schnell das Problem, wie man die Daten darstellt, wenn die beiden verknüpften Datensätze eine unterschiedliche Struktur aufweisen. Die zweite Idee wäre es, ähnlich wie das Programm Finder auf dem Mac zu agieren, allerdings die Anordnung zu ändern: es gibt zwei Tabellen, die untereinander liegen. Selektiert der Benutzer in der oberen Tabelle einen Datensatz so werden in der darunter liegenden die Datensätze, samt aller Informationen, angezeigt, die mit dem selektieren verknüpft sind. Leider findet hier eine visuelle Trennung statt.
Manchen gefallen Tabellenstrukturen, da alle Daten auf einen Blick ersichtlich sind (in so fern diesen auf den Bildschirm passen), ich bin aber eher ein Verfechter, dass es eine Alternative geben muss. Ergänzungen des Konzepts sind unbedingt notwendig, um dem Benutzer ein ordentliches und schnelles Arbeiten zu ermöglichen. Allerdings sollte man immer darüber nachdenken, andere Dinge auszuprobieren und zu evaluieren. Steht etwas mehr Spielraum zur Verfügung, so kann man durchaus dreidimensionale Modelle bemühen oder evtl. auf einen Zoom-Effekt setzen.
Jan 28th
Hinweis: Vorab muss ich sagen, dass ich jedes Projekt (bisher) unter Windows erstellt habe und somit nur die Windows-Clienten verwende.
CVS habe ich schon von Anfang aus ausgelassen, da dem SVN nachgesagt wurde, dass es die Weiterentwicklung und somit in einigen Punkten besser ist. Ich habe das nie näher verfolgt und kann das somit auch nicht weiter bestätigen oder dementieren. Somit bin ich gleich mit dem TortoiseSVN-Client eingestiegen und war echt zufrieden damit.
Musste ich mal selbst einen SVN Repository anlegen, so habe ich auf einer Linux-Maschine das Apache-Modul eingesetzt. Unter Windows nutzte ich die Software VisualSVN. Online hatte und habe ich mehrere Repositories auf Projectlocker.com, wo man kostenlos SVN und GIT gleichzeitig nutzen kann, natürlich nicht für ein Projekt, schon mal als Tipp für alle potentiellen späteren Git-Nutzer ;)
Solange das SVN Repository erreichbar war, war SVN echt klasse, da ich immer und überall committen konnte. Nur wenn man mal unterwegs war, oder eben keinen Zugriff gehabt hatte, war das committen (soweit ich weiß) einfach nicht möglich. Somit wurde innerhalb eines Commits sehr viel Änderungen übergeben, welches das Zurücksetzen nicht so toll gestaltete.
Überrascht wurde ich vor längerer Zeit von Git. Ich bin mehr oder weniger durch Zufall darauf gestoßen und habe mir ein paar Dinge von einem Kommilitonen zeigen lassen. Hier nur ein paar Dinge, die ich (nach einiger Nutzung) besser finde:
Weiter bin ich in der Nutzung noch nicht gekommen, da ich immer alleine das Repository genutzt habe :) Branches und dergleichen habe ich mir noch nicht angeschaut. Somit kann ich über diese Features auch noch nichts sagen.
Ich hoffe, ihr habt ein wenig einen Eindruck von Git erhalten. Vor allem, wenn man schon erfolgreich SVN einsetzt sollte man sich überlegen, ob man nicht umsteigt. Es fehlen bisher immer noch gute (native) Integrationen in IDEs, als dass es bisher etwas ausmachen würde, welches System man nutzt.
In diesem Sinne noch einen schönen Donnerstag.
Jan 25th
Ich habe mich gerade von einem Kommilitonen korrigieren lassen müssen, da ich bisher immer der Annahme war, dass das Board meines Zweitrechners kein Wake-On-Lan (WOL) unterstützt. Selbst der ASUS-Support (ja, so etwas gibts es wirklich! :) ) war der Meinung, dass so etwas mit diesem Board nicht funktioniert.
Aber: es funktioniert eben doch! Man muss dazu im BIOS die Funktion Power On By PCI Devices aktiveren und dann ab ins Betriebssystem gehen. In meinem Fall war dies Linux (Ubuntu 9.10). Dort kann man über das Programm ethtool die entsprechende Netzwerkkarte konfigurieren. Auf ubuntuusers findet ihr eine genaue Anleitung, was alles zu tun ist.
In Verbindung mit diesem Wake-Up-Tool kann man unter Windows sehr schnell eine Batch-Datei schreiben und den gewünschten Rechner aufwecken. Unter Ubuntu kann man etherwake nutzen, zu dem, in den weiter oben genannten Link, weitere Informationen zu finden sind. Ich habe mir in der Zwischenzeit sogar Freetz auf meine Fritz Box 7170 installiert und habe somit ein Webinterface, über welches ich meine Rechner daheim hochfahren lassen kann; sehr bequem, wie ich finde ;)
Dec 3rd
Als ich heute morgen um 5 Uhr ins Bett gegangen bin war ich mit dem Nerven am Ende. Ich habe versucht die aktuelle Datenbank von Oracle auf meinem Ubuntu-Rechner zu installieren. Vorab gibt es zu sagen: eine einfache Installation ist nicht möglich.
Mein erster Versuch war es, die neuste Version der Express-Datenbank, also 11g Release 2, herunterzuladen und zu installieren. Es gibt einen Installer, der dem ZIP-Paket beiligt. Während des Setups kamen ein paar Hinweise, dass mein System nicht die Voraussetzungen erfüllt ‒ unter anderem ist der Test der installierten make-Version fehlgeschlagen, da eine neuere Version installiert ist. Diese habe ich ignoriert, in der Hoffnung, dass das Setup trotzdem alles nötige installiert. Während der Installationsvorgangs meldete sich sich der Installer immer wieder und meldete Fehler, zu denen ich im Netz keine Lösungen gefunden habe. Somit scheiterte die Installation erfolgreich.
Den zweiten Versuch startete ich mit einer Anleitung, welche ich im Netz gefunden hatte. Diese spezifizierte den Release der Datenbank aber nicht näher und somit versuchte ich erneut den R2 zu installieren. Lustig an dieser Installation war allerdings, dass noch mehr Fehler auftauchten und Inhalte auf Formularen teilweise nicht sichtbar waren.
Einen weiteren Versuch startete ich mit dieser Anleitung auf pythian.com. Der Autor verwendete hierbei allerdings eine ältere Ubuntu-Version und auch der Release 1 der Datenbank. Dieser liefert einen anderen Installer. Ich befolgte die Anleitung sehr präzise und bin kaum auf Probleme gestoßen, da alles bis ins letzte Detail beschrieben wird.
Allerdings teilte mir der Installer erneut zwei Fehlermeldungen mit, die allerdings keinerlei Auswirkungen auf das laufende Produkt haben. Ich kann die Datenbank ohne Probleme nutzen und alles läuft, wie ich es erwarte. Ich hoffe, dass das hier einigen Menschen helfen kann, da diese Anleitung viel Zeit und Nerven sparen kann.
Sep 30th
Ich habe ein Abo bei einer bekannten Computer-Zeitschreift, die neulich meine neueste Studienbescheinigung haben wollte, sodass ich dies weiterhin zu den vergünstigsten Konditionen bekomme. Nun ja, ich hatte eine bei mir zu hause und wollte diese sofort scannen und abschicken. Ich habe meinen Scanner HP ScanJet 4200C an meinen Rechner mit Windows 7 angeschlossen und siehe da, nichts funktionierte.
Wie man auf der Website schwerlich erkennen kann gibt es nur bis einschließlich Windows XP Treiber für diesen Scanner. Unter Windows 7 habe ich nach ein wenig Probieren keine Erfolge erzielen können. Irgendwie habe ich eine offizielle Information gefunden, dass der Scanner leider nicht mehr und Vista und 7 funktioniert.
Aber einfach den Scanner wegwerfen und neu kaufen ist doch blöd. Ich bin dann irgendwie auf die Idee gekommen, eine virutelle Maschine (mit Windows XP) für so etwas zu missbrauchen, wobei mir VMware Workstation zur Seite stand. Ich habe den Scanner an meinen PC angeschlossen, den USB-Anschluss, an dem der Scanner hieng, mit der virtuellen Maschine verbunden und siehe da, alles hat funktioniert ;)
Ich denke, dass diese Kniff vielleicht bei Microsoft’s oder Sun’s Virtualisierer auch funktionieren kann und somit bekommt man wohl wiede rein paar mehr Geräte zum laufen. Mir ist schon klar, dass das in vielen Fällen, wie z.B. das Drucken, sehr kompliziert werden kann, aber es ist wohl noch wesentlich günstiger diese Lösung einzuschlagen, als sich einen neuen Drucker zu kaufen.
Sep 10th
Ich hab schon auf einigen Seiten einen Besucherzähler verwendet, der sehr einfach gehalten ist. Viele andere sind (mir) zu komplex und bieten mehr als man will, oder werde gar auf anderen Seiten gehostet, wie z.B. Google Analytics. Mir ist durchaus klar, dass das gerade erwähnte Beispiel eine eierlegende Wollmilchsau ist und man fast unendlich Möglichkeiten hat, aber es muss beim Seitenaufbau dennoch Code von einer anderen Seiten geladen werden. Bei externen Anbietern stellt sich zudem allgemein immer auch die Frage: wie lange wird dieser Service noch angeboten? Was passiert bei Updates? Was passiert, wenn dieser eines Tages mal abgeschaltet werden sollte?
Daher habe ich gerne eigenen Code auf meiner Website, der somit eigentlich auch recht schnell geladen bzw. vom Parser bearbeitet wird. Ein Zugriff auf einen anderen Webserver ist nicht nötig und spart somit Zeit. Ein, wie ich finde gutes Beispiel ist der pCounter von Andreas Droesch. Ein implementiertes Beispiel findet man ganz unten, im Footer einer Seite, die ich umgesetzt habe: Internationale Giuseppe Verdi Stiftung.
Für den normalen PHP-Programmierer reicht der Code, der auf der Website zum Download angeboten wird. Ich verwende allerdings das Yii-Framework, welches einem viel Arbeit beim programmieren einer Website erspart. Dieses Framework hat auch den Vorteil, dass man Erweiterungen programmieren und der Community zur Verfügung stellen kann. Dies habe ich mit dem pCounter nun gemacht, entsprechende portiert und veröffentlicht: Download.