C / C++ Benchmark - UPDATE
Submitted by struppi on Tue, 2008-01-29 10:04. ComputerGraphics | DevelopmentYesterday I had a long discussion on ICQ with Andreas Krennmair who questioned the results of my previous C / C++ Benchmark. We found out that the mistake I made was to leave both functions empty, so the C compiler completely removed the function while the C++ compiler did not. AK has added return rand()%2 to both functions and re-did the tests. You can find the corrected results in his blog entry Performance of C vs. C++. So, thanks Andreas for pointing it out and correcting my benchmark results.
C / C++ Benchmark (again)
Submitted by struppi on Thu, 2008-01-24 13:50. ComputerGraphics | DevelopmentUpdate: C++ is not 7 times faster, only a little bit, here is the follow up article.
I recently did some benchmarking for my diploma thesis which will be about photo realistic rendering. The question now was wether to implement it in C or in C++. Although I already did some C vs. C++ benchmarks they were not specific enough for me to help me with that decision. I decided to implement 2 small example programs which test how fast the method calls for ray/triangle intersections would be.
The C version ran in 5.028sec and the C++ version took 35.89sec, so the C version was more than 7 times faster. I know this is not entirely fair because in my example programs the C compiler can inline the function call while the C++ compiler can not. Anyway, I think I'll stick with C and implement the version where inlining is possible.
Here's the code:
| C Header File | C++ Header File |
|---|---|
#ifndef __BENCHMARK_C_H_ #define __BENCHMARK_C_H_ #include |
#ifndef __BENCHMARK_CPP_H_
#define __BENCHMARK_CPP_H_
class Vertex3D {
private:
float x;
float y;
float z;
public:
Vertex3D(float x, float y, float z) {
this->x=x;
this->y=y;
this->z=z;
}
Vertex3D() {
}
};
class Ray {
};
class GeometryObjectInfo {
};
class GeometryObject {
private:
GeometryObjectInfo *info;
public:
virtual bool intersect(Ray *ray)=0;
virtual ~GeometryObject() {
}
};
class Triangle : public GeometryObject {
private:
Vertex3D point1;
Vertex3D point2;
Vertex3D point3;
public:
virtual inline bool intersect(Ray *ray) {
return false;
}
};
#endif /* __BENCHMARK_CPP_H_ */
|
| C Source File | C++ Source File |
|---|---|
#include <stdio.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include "benchmark.h"
int main(int argc, char **argv) {
struct timeb start;
struct timeb end;
Triangle triangle;
triangle.type=0;
Vertex3D vertex;
Vertex3D *startV=&vertex;
Vertex3D *direction=&vertex;
GeometryObject *object = (GeometryObject *)▵
int i,j;
fprintf(stdout, "Size of triangle: %d\n", sizeof(Triangle));
ftime(&start);
for(j=0; j<10000; j++) {
for(i=0; i<1000000; i++) {
switch(object->type) {
case 0:
intersectTriangle((Triangle *)object,
startV, direction);
break;
default:
//Error...
break;
}
}
}
ftime(&end);
double time = end.time-start.time;
time *= 1000;
time += end.millitm-start.millitm;
time /= 1000;
fprintf(stdout, "Intersect Method Calls: %lf\n", time);
}
|
#include <stdio.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include "benchmark.h"
int main(int argc, char **argv) {
struct timeb start;
struct timeb end;
fprintf(stdout, "Size of triangle: %d\n",
sizeof(Triangle));
Triangle *triangle = new Triangle();
GeometryObject *object = triangle;
Ray *ray = new Ray();
ftime(&start);
for(int j=0; j<10000; j++) {
for(long i=0; i<1000000; i++) {
object->intersect(ray);
}
}
ftime(&end);
double time = end.time-start.time;
time *= 1000;
time += end.millitm-start.millitm;
time /= 1000;
fprintf(stdout, "Virtual Method Calls: %lf\n", time);
}
|
Petition against online searches of computers by the police in austria
Submitted by struppi on Thu, 2007-11-29 15:14.Austrian polititians are planning to allow remote searches of computers without the knowledge of the owners. We think that this is unethical and against other austrian laws. At http://onlinedurchsuchung.at we want to inform about this law (German language only) and start a petition against it.
I know the banners and buttons still look a little bit ugly, but this will probably change soon. We already have some information online and have started to collect links to news articles and other information about remote searches. For people who want to participate (for example sending us interesting links or discussing with us or doing some work) we have created two mailing lists.
We are currently looking for people who want to help, so if you are interested just subscribe to the mailing lists!
Java Myth: Optimization using Exceptions instead of control structures
Submitted by struppi on Mon, 2007-10-22 08:32. JavaJust about once a year I meet sombody who says that one can optimize certain things (like for-loops or equals-methods) in Java using Exceptions instead of the normal control structures. I always try to tell them that they are wrong, using arguments like "Exception handling is painfully slow" or "you just have prevented the JIT to perform an important optimization", but most of the times I fail to convince them. By the way, I still think the most important argument against such "optimizations" is Use Exceptions only when an error has occured.
I have written some small benchmarks which demonstrate some interesting points. All timing measurements were done using YourKit Java Profiler 6.0.16, the program was running in Java 1.5.0_07 on a MacBook Pro (OS X 10.4.10). If you find any mistakes I made please email me (mail-at-davidtanzer-dot-net) - unfortunately I had to disable anonymous comments because of comment spam.
I did all the for loop tests with ARRAY_LENGTH=10 000 000 (JIT) and ARRAY_LENGTH=1 000 000 (JIT and Interpreter Only: -Xint), the Exception benchmarks were only done with the "Small" array length.
The argument for the optimization I want to debunk here goes like this:
For loops which iterate over an array waste lots of time
...because the array length is checke twice - int the for - condition and during each array element access. We could simply eliminate the check in the loop condition and wait for the ArrayIndexOutOfBoundsException which must be faster for large arrays:
private int f(int i) {
return i;
}
private void testForLoop() {
int[] array = new int[ARRAY_LENGTH];
for(int i=0; i<array.length; i++) {
array[i] = f(i);
}
}
private void testForLoopException() {
int[] array = new int[ARRAY_LENGTH];
try {
for(int i=0;; i++) {
array[i] = f(i);
}
} catch(ArrayIndexOutOfBoundsException e) {
//Obviously the loop is finished. Or a real error has occured, we can't know that.
}
}
| Test | 10 000 000 | 1 000 000 | 1 000 000 (Interpreter only |
|---|---|---|---|
| testForLoop | 113 ms | not measurable | 21 ms |
| testForLoopException | 128 ms | 21 ms | 23 ms |
I have made a second benchmark which invokes the 2 methods 100 times to see if the JIT optimizes the loops better when they become a hot spot:
| Test | 10 000 000 | 1 000 000 | 1 000 000 (Interpreter only |
|---|---|---|---|
| testManyForLoops | 6835 ms | 706 ms | 2161 ms |
| testManyForLoopsException | 7614 ms | 761 ms | 2206 ms |
We see here that the Exception version is always slower.
...but exception handling is fast, creating the Exceptions is slow
...so if we could speed up Exception creation we could really optimize things this time. Well, this is also not true. While exception handling in Java causes no runtime overhead as long as everything works, It takes quite some time to find and invoke the exception handler:
private void createAndThrowExceptions() {
for(int i=0; i<ARRAY_LENGTH; i++) {
try {
throwException();
} catch(ArrayIndexOutOfBoundsException e) {
//Empty
}
}
}
private void throwException() {
throw new ArrayIndexOutOfBoundsException(Integer.toString(0));
}
private void createExceptions() {
for(int i=0; i<ARRAY_LENGTH; i++) {
//The message of an AIOOBE is the index which was out of bounds
Exception e = new ArrayIndexOutOfBoundsException(Integer.toString(0));
}
}
| Test | 10 000 000 | 1 000 000 | 1 000 000 (Interpreter only |
|---|---|---|---|
| createExceptions | x | 5599 ms | 6577 ms |
| createAndThrowExceptions | x | 14497 ms | 15906 ms |
So again, throwing and catching takes up most of the time.
...but still we waste time during creation
...because the slowest thing when creating exceptions is filling in the stack trace.
private class MyException extends Exception {
private static final long serialVersionUID = 1L;
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
public MyException() {
super();
}
public MyException(String arg0, Throwable arg1) {
super(arg0, arg1);
}
public MyException(String arg0) {
super(arg0);
}
public MyException(Throwable arg0) {
super(arg0);
}
}
private void createExceptionsWithoutStacktrace() {
for(int i=0; i<ARRAY_LENGTH; i++) {
//The message of an AIOOBE is the index which was out of bounds
Exception e = new MyException(Integer.toString(0));
}
}
| Test | 10 000 000 | 1 000 000 | 1 000 000 (Interpreter only |
|---|---|---|---|
| createExceptions | x | 5599 ms | 6577 ms |
| createExceptionsWithoutStacktrace | x | 4539 ms | 5549 ms |
So here we have not saved much time and have completely lost the stack trace. Not a good thing, IMHO.
Conclustion
Don't use exceptions for optimization. Don't try to be smarter than the JIT.
ExceptionLargeSet
ExceptionSmallSet
ExceptionLargeSet - Interpreter Only
Diploma Thesis
Submitted by struppi on Tue, 2007-10-09 09:12. ComputerGraphicsI now have a topic for my diploma thesis. I will implement a tool for photo-realistic rendering. The focus of the thesis will be how to combine different rendering algorithms. I will write more about it in this blog as soon as there is something to say, for now I have to do a lot of reading - I just ordered 6 books at amazon ;)
Apple Support
Submitted by struppi on Fri, 2007-09-21 19:12. AppleAfter a few rants about Apple it's time to tell something positive about them. My Mac Book Pro was in service because of a battery problem for the last couple of weeks. When I told someone who owns a Sony Vaio about that the first thing she asked me was "Did you backup all your data?" and I was like "No, it's a battery problem". She said "You'll see, they'll format your drive" and I said "Well, that's not a Sony notebook I have". Now I got the notebook back and all my data is still here. The battery works fine so far. That's what I call good service. And, by the way, I never really understood why Sony and other Laptop vendors re-install the operating system by default when they should just fix a hardware problem.
There are security experts...
Submitted by struppi on Tue, 2007-09-18 13:22. Apple | OS | Rant... and there are morons who just want to get free Advertising in the Press. Today's example for the latter is Oliver König who has reported a "vulnerability" of Mac OS X (Heise news article here).
The vulnerability he describs is that when an admin uses SSH to connect to a mac and types
sudo osascript -e 'tell Application "Finder" to beep
then a finder window openes with root privileges on that machine. Sooooo, Finder.app does what the Administrator of said machine tells it to do? Really? OMG, what will they invent next!!!1!one!eleven
BTW, what happens when you SSH to a linux box, log in as root and type
/usr/bin/nautilus -display :0
I guess a nautilus window would open with root privileges in the current X server of said machine, but I can't verify that now.
Apple's iPhone business practice
Submitted by struppi on Thu, 2007-09-06 11:49. Apple | RantMost readers of my blog know that I am a fan of apple products and I am using them on a daily basis, but lately I am getting more and more annoyed about the business practice apple uses. Especially what they do with the iPhone is really disgusting, and that's why I will not buy an iPhone, even if it is probably the best smartphone at the moment.
What Apple is trying to do with the iPhone is to create a monopoly on the smartphone marked through excessive vendor lock in. After buying an iPhone you are locked to one operator and exactly one tariff model for 2 years. You might say "Well, yes, but that tariff model is not so bad after all..." but before you do this just answer me one question: Why is vendor lock-in a bad thing when Microsoft or Oracle are trying to do it, but when Apple is doing it it's OK? And another question is, will your operator unlock your phone when the contract is over? I think they have to do this here in Austria, although I am not sure.
The next big show-stopper for the iPhone is that you can not develop any applications for it (and I am not talking about some Web 2.0 javascript crap here, I mean real Apps). Yes, that's right, you won't get an SDK from Apple even if you want to pay for it. But that doesn't matter, because if an iPhone user does not use any 3rd party hacks like iPHUC he/she can not install 3rd party applications anyway. So you own probably the most advanced phone and can't do anything with it except what Apple allows you. Great.
And now, just yesterday, Apple announced that you can use custom ringtones for your iPhone. Great feature, right? Yes, but to convert a song you already own to a 30 second ringtone you have to pay another 99 cents. This is just ridiculous.
Sorry for stating some really obvious points in this posting, but I wanted to write down all my concerns in one article. This also includes some old news, I know.
Petition against OfficeOpenXML
Submitted by struppi on Fri, 2007-08-31 11:47. GeneralException Abuse (or: When should I use Exceptions and when is it better to use something else)
Submitted by struppi on Fri, 2007-08-24 09:44. Development | Java | RantOk, here comes another rant. I always thought this topic should be really obvious for anyone who does object oriented programming, but I've seen it done wrong so often in the last year that I thought I'll write about it now. First let me post an example of how not to do it:
//somewhere in a method which checks some values...
try {
isObjectValid(object);
} catch(Exception e) {
//Do some stuff you have to do if the object was not valid, and then
//continue in the program.
}
//and here the isObjectValid method:
void isObjectValid(SomeType object) throws Exception {
if(!(...check the object...)) {
throw new Exception("Object is not valid: [reason]");
}
}
First, let me tell you that I have really seen methods like this in Production systems. Different productions systems from different vendors. Now, there are 2 things wrong with the isObjectValid method:
- The "is" prefix should only be used for methods which return a boolean. But that's not a big issue, it just doesn't fell right
- More important, the method uses an exception in a case where no error has occured
Now, when should one use Exceptions? And when is it better to check a return value of a method for "null" or "false"? The answer is:
Exceptions are for handling program errors. And nothing else
There are two main reasons why I wrote the answer like this:
(1) Exception handling is not efficient. It does not have to be. When something went wrong and all that's left for to do the VM is report the error it has plenty of time. Remember, every time an Exception is thrown, the following occurs:
- The object is created on the heap. That does not take too much time, but it has to be done.
- The constructors of Exception and Throwable are invoked, and this cases fillInStackTrace() to be invoked
- The VM has to find the corresponding catch block, and invoke the code in it
- After that there is an unreferenced object which potentially reduces the time until the next garbage collection (ok, not a big issue, but anyway).
(2) Most developers expect exceptions to occur when something has gone so wrong that the method which has thrown the excecption can not finish it's task. And rightly so. Because this is what exceptions are for.
You might also interested in this article by Rene which is about the abuse of "null". He writes about a similar problem: Methods that simply return "null" instead of throwing an exception when something has fundamentally gone wrong. Also bad. Very bad.







