Weve 2.0.3 Beta no comments
After a long absence, I’ve brought back WEVE (Windows Environment Variable Editor). I use it a lot, and quite a few people got some good use from Weve 1.5. This came about when today I got an email from Robert Hadjiyski asking what ever happened to WEVE, and if I would be able to provide the source code so that he may make bug fixes/improvements.
This reminded me that I had Weve 2.0 sitting around on my HDD gathering dust. So I’ve put the binaries up in a ZIP file, and I have applied to have a source forge page created to host/manage the project’s source code. At some stage I’ll update the MSI installer project and stick that version up too.
Hope people like the 2.0 improvements, alot of handy features that make WEVE 2.0 even easier and more intuitive to use than 1.5.
Get it from the WEVE page
XSLT and Java Quick Tips (Xalan) no comments
Recently at work, I’ve been using XSLT transforms in our backend quite a bit. But the issues I’ve run into took stupid amounts of effort to resolve and it wasnt easy to find any kind of list of do’s and dont’s - so I’m gonna make one from the stuff I’ve just discovered!
- When dealing with DOMSource and DOMResult - always setNamespaceAwareness(true) on your DocumentBuilder/DocumentBuilderFactory !!! - otherwise you end up with empty Documents and no indicators as to why!
- Remember that an XSLT transformation is not guaranteed to return an XML document! Hence, Don’t automatically assume a DOMResult( docBuilder.newDocument() ) will return a valid object - if your XSLT doesn’t produce valid XML, you’ll get an empty DOMResult document node!
- Validation settings affect whitespace awareness - if you don’t have validation on, whitespace is NOT ignored, so make sure your XSLT is formatted correctly - the most common problem area is when you try to prettyfy your .xsl file using indentation etc. Remember that XSL is pretty much an in-place tempate file [Copy Contents -> Replace Stuff exactly where it's asked for -> Dump result!]
Lastly, and easy way to transform input XML and pretty print it.
TransformerFactory transfac = TransformerFactory.newInstance(); Transformer trans = transfac.newTransformer(); trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); trans.setOutputProperty(OutputKeys.INDENT, "yes"); Document doc = buildXml(); /* get your XML document from somewhere.. */ StringWriter stringWriter = new StringWriter(); StreamResult result = new StreamResult(stringWriter); DOMSource source = new DOMSource(doc); trans.transform(source, result); System.out.println(stringWriter.toString());
Boost signals (1.36.0) vs. sigc++ (2.0.18) no comments
Recently my engine has needed an upgrade to its event system (observer/publisher). Currently, there is little overhead involved but this is achieved by using macro’s which inline function calls. This is neither maintainable nor extensible and has lead to problems while trying to develop a reliable shutdown sequence for the engine (e.g. when fatal exceptions are caught) - this is mainly due to the intense parallelism present in the architecture.
I found several implementations of the “signals & slots” design pattern, the stand-outs were boost::signals, sigc++-2.0 and a very lightweight implementation called sigslot-1-0-0.
Reading on the internet (boost mailing lists as well as Sneftel’s post on GDnet) lead me to believe that boost::signals had performance issues, however with the recent release of 1.36.0 I wasn’t sure about how valid these bits of information were, so I spent a few hours today developing a benchmark which netted the results inserted at the end of this post.
The signals_bench.cpp C++ source code is not as simple as it could be, but should be easy enough to follow. I chose to use templates/compile time code generation to keep runtime overhead low and also as a bit of practice, as my full-time job is uses Java.
So Boost seems to be faster when you have many signals and many slots for each signal. The 1000×1000 test returned 22 seconds for sigc++ and only 3 seconds for boost::signals. Don’t really know why, but it’s a bit out of place when you take note that boost signals basically gets its ass handed to it by sigc++ in all the other tests. the 5×100000 test b::s returns 1.5 seconds where sc++ returns 0.5 seconds.
The next thing to test is multi-threaded performance, neither library natively supports threading, however sigc++ has an addon called sigc++extras or sigcx, interestingly sigslots is already thread safe. I will have to manually wrap boost::signals so that will be interesting to do..
I will be including sigslots in the next round of testing… whenever that is. (I ran out of time today, might repost with those results if I have time this week)
Just on a side note, the two libraries syntaxes are so similar, you may be able to develop a hybrid wrapper which can switch libraries at runtime. Would be interesting to see how this would help if it were used in a “real-world™” scenario.
Results
| description | setup time | run time | signals | slots | |
|---|---|---|---|---|---|
| boost::signals 1.36.0 | 0.003000 | 2.988000 | 1000 | 1000 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 100 | 1 | |
| boost::signals 1.36.0 | 0.000000 | 0.003000 | 100 | 10 | |
| boost::signals 1.36.0 | 0.000000 | 0.029000 | 100 | 100 | |
| boost::signals 1.36.0 | 0.000000 | 0.001000 | 5 | 1 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 5 | 10 | |
| boost::signals 1.36.0 | 0.000000 | 0.001000 | 5 | 100 | |
| boost::signals 1.36.0 | 0.001000 | 0.015000 | 5 | 1000 | |
| boost::signals 1.36.0 | 0.001000 | 0.148000 | 5 | 10000 | |
| boost::signals 1.36.0 | 0.010000 | 1.487000 | 5 | 100000 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 4 | 1 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 4 | 10 | |
| boost::signals 1.36.0 | 0.000000 | 0.001000 | 4 | 100 | |
| boost::signals 1.36.0 | 0.001000 | 0.012000 | 4 | 1000 | |
| boost::signals 1.36.0 | 0.001000 | 0.119000 | 4 | 10000 | |
| boost::signals 1.36.0 | 0.011000 | 1.189000 | 4 | 100000 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 3 | 1 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 3 | 10 | |
| boost::signals 1.36.0 | 0.000000 | 0.001000 | 3 | 100 | |
| boost::signals 1.36.0 | 0.000000 | 0.008000 | 3 | 1000 | |
| boost::signals 1.36.0 | 0.001000 | 0.090000 | 3 | 10000 | |
| boost::signals 1.36.0 | 0.011000 | 0.895000 | 3 | 100000 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 2 | 1 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 2 | 10 | |
| boost::signals 1.36.0 | 0.000000 | 0.001000 | 2 | 100 | |
| boost::signals 1.36.0 | 0.000000 | 0.006000 | 2 | 1000 | |
| boost::signals 1.36.0 | 0.001000 | 0.059000 | 2 | 10000 | |
| boost::signals 1.36.0 | 0.011000 | 0.585000 | 2 | 100000 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 1 | 1 | |
| boost::signals 1.36.0 | 0.000000 | 0.000000 | 1 | 10 | |
| boost::signals 1.36.0 | 0.000000 | 0.001000 | 1 | 100 | |
| boost::signals 1.36.0 | 0.000000 | 0.003000 | 1 | 1000 | |
| boost::signals 1.36.0 | 0.001000 | 0.029000 | 1 | 10000 | |
| boost::signals 1.36.0 | 0.011000 | 0.291000 | 1 | 100000 | |
| sigc++ 2.0.18 | 0.000000 | 21.526000 | 1000 | 1000 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 100 | 1 | |
| sigc++ 2.0.18 | 0.000000 | 0.001000 | 100 | 10 | |
| sigc++ 2.0.18 | 0.000000 | 0.012000 | 100 | 100 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 5 | 1 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 5 | 10 | |
| sigc++ 2.0.18 | 0.000000 | 0.001000 | 5 | 100 | |
| sigc++ 2.0.18 | 0.000000 | 0.005000 | 5 | 1000 | |
| sigc++ 2.0.18 | 0.000000 | 0.046000 | 5 | 10000 | |
| sigc++ 2.0.18 | 0.000000 | 0.473000 | 5 | 100000 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 4 | 1 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 4 | 10 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 4 | 100 | |
| sigc++ 2.0.18 | 0.000000 | 0.004000 | 4 | 1000 | |
| sigc++ 2.0.18 | 0.001000 | 0.037000 | 4 | 10000 | |
| sigc++ 2.0.18 | 0.000000 | 0.378000 | 4 | 100000 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 3 | 1 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 3 | 10 | |
| sigc++ 2.0.18 | 0.000000 | 0.001000 | 3 | 100 | |
| sigc++ 2.0.18 | 0.000000 | 0.002000 | 3 | 1000 | |
| sigc++ 2.0.18 | 0.000000 | 0.029000 | 3 | 10000 | |
| sigc++ 2.0.18 | 0.001000 | 0.287000 | 3 | 100000 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 2 | 1 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 2 | 10 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 2 | 100 | |
| sigc++ 2.0.18 | 0.000000 | 0.002000 | 2 | 1000 | |
| sigc++ 2.0.18 | 0.000000 | 0.020000 | 2 | 10000 | |
| sigc++ 2.0.18 | 0.001000 | 0.196000 | 2 | 100000 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 1 | 1 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 1 | 10 | |
| sigc++ 2.0.18 | 0.000000 | 0.000000 | 1 | 100 | |
| sigc++ 2.0.18 | 0.000000 | 0.001000 | 1 | 1000 | |
| sigc++ 2.0.18 | 0.000000 | 0.010000 | 1 | 10000 | |
| sigc++ 2.0.18 | 0.001000 | 0.110000 | 1 | 100000 |
Super-quick-how-to install Boost 1.36.0 1 comment
Just because for a standard install, its really simple, but you have to read the getting started guide which has alot of info, but it’s not necessarily “to the point”, if you know what I mean.
- Download Boost 1.36.0 and Bjam (http://www.boost.org/users/download)
- Add Bjam to the PATH if you haven’t already
- Navigate into where you extracted the boost code, the folder is probably named “boost_1_36_0″… e.g. cd C:\Libraries\boost_1_36_0
- invoke bjam with the following arguments: <configuration> –toolset=msvc <output directory name>. e.g. “bjam debug –toolset=msvc stage” builds the entire boost library, and spits out debug .dll’s and .lib’s into “C:\Libraries\boost_1_36_0\stage\libs”
- Add/update these paths in your IDE or your LIB and INCLUDE environment variables e.g. in MSVC I updated my VC include directory list to have “C:\Libraries\boost_1_36_0″ and my VC lib directory list to have “C:\Libraries\boost_1_36_0\stage\libs”
- in your C++ #include <boost/MODULE.hpp> and you should be good to go! (with MSVC the appropriate lib is automatically linked against, if you’re directories are all good, you shouldn’t have to modify your individual project settings)
- Write awesome C++ code!!
Coming soon… no comments
The blog has been playing up lately, looks like it is sorted now, and it will be getting up and running soon.