- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
I'd like to see you produce some evidence of that...
Admin
Except that if he were fired because of this code, then they probably would have known about it and removed it before the app server ran out of disk space. (I thought it was fairly clear from the post that the de-hiring was prior to the crash, at least.)
Admin
Aren't lots of major improbabilities involved with everything we ever see on this site?
Admin
Scope creep?
If its agreed to and signed off, no one can say 'oh, but what i really meant when i said...'
because u can turn around and reply 'piss off, this is the spec.'
Admin
he dehired himself?
Admin
oh dammit, someone beat me to that joke... hiding away there on the second page...
anyway, aside from all the WTF's about why you'd do this, there's a parallel WTF of why he didn't use:
String mySabotageAttempt = "";
for (i = 0; i < 16384; i++) {
mySaboutageAttempt += "*";
}
maybe he was concerned about the memory use of using a variable instead of a constant.
Admin
No.. actually the "de-hired" man with his atitude was a "drag queen" ...
LOL :)
Admin
Don't do that! You need to use newline... \n
That way you make very long lines... word wrap is very time consuming on the Notepad!
You should "stick" (with) the original code ;)
Admin
<font size="6"> W</font>ell, what about having the engineers create and run unit tests before merging into the next version and sending it to the testers?
What! We don't have time for that. We aren't in school anymore. Damn! Damn! Damn! If this project doesn't turn around I won't get my executive bonus this year.
Admin
He certainly wasn't concerned with anyone spotting the multi-page string costant composed of ****s.
Admin
StringBuilder, StringBuilder...
Or even just
String myGodItsFullOfStars = "*";
for (i = 1; i <= 14; i++) { // 16K is 2**14
myGodItsFullOfStars += myGodItsFullOfStars;
}
Admin
I love how everyone is trying to improve this trash. I just love TDWTF.
Admin
God hates also your football team and wants mine to win.
Admin
Dammit Jim, I'm a doctor, not a code monkey!
Admin
ok, that's actually faster... but the longass for loop (first response) is more wtf... the code he had in the first place is FASTER (for loops!). So, somehow, in his retarded head, he managed to optimize (partially) completely wtf worthy code... www.WTF.com.... or should I say www.thedailyWTF.com!
Admin
Would you prefer 'drug himself out of bed?'
Admin
You mean because that way, he could have wasted CPU time as well as diskspace?
The code above does a total of about 256MB of temporary storage allocation - lots of work for the garbage collector. I don't think there even is a CPU that could do it within a second...
Admin
As usual, every one is bashing. But... if the requirement was to be 100% sure that the log is written, how would you do? Suppose this is java and the logging API was used. There is no flush() method in the Logger class. No flush() call is done by the standard StreamHandler class. Yes you could write your own handler but maybe it was not an option. Seems the logger/handler was part of a framework and there is probably no way to access it. So I ask you: how would you do?
Admin
If it required a hack even a fraction as bad as that, live with it and mark the issue as unfixable, if the library couldn't be switched for something else or extended. And make sure that whoever decides what libraries to use actually evalulates them properly in future.
Admin
Ok, I've never used the Logger API, and just took a 15 second look at the JavaDoc page, and the solution is obvious to me.
There is no flush() in the logger class because it doesn't WRITE any logs, it only passes messages to the apropriate HANDLER. The Handler interface specifies a flush method.
Logger.getHandlers() gives you an array of all the installed handlers, and you can just call flush on them. Or write your own MyAlwaysFlushingHandler, extend StreamHandler and add a flush() call in the publish() function.
Admin
The loop doesn't use massive cpu - you do it once at class load time.
Admin
The String variable in that code snippet was not declared static or final, so it doesn't look like that. From the "sabotage" point of view, doing it every time is certainly better - unless it leads to a too-early discovery. It's a tradeoff.
Admin
Well of course, that is why the original was a constant string. Even if they guy knew about for loops (which judging by thedailywtf is about 50% chance), there isn't a chance that he also knew about modular arithmetic. Thus he couldn't get the newlines in anyway without the hardcoded string.
Admin
Maybe he is using a singleton pattern, so that even though the String is not static or final, he knows it is only initialized once. :)
Admin
Erm... even python code does that pretty much instantly and without noticeable memory consumption (CPU takes a hit though).
Admin
ok, that's funny.
Admin
We can still pessimize it further...
String mySabotageAttempt = "";
while( mySabotageAttempt.length() < 16384) {
mySaboutageAttempt += "*";
}
Admin
I have an even better idea...
Instead of loading the class and instantiating the object from scratch, we could load a serialized version!
Admin
And with good reason.
Are you trying to say that under some set of circumstances, you would actually contemplate writing 16K worth of *'s to a log in order to flush it?????
Admin
1) Write each second's log entry to a new SQL Table. (Hey - it'll get noticed sooner, and it doubles up the WTF!)
2) Use REs in post-processing to eliminate the waste ... s/*//g
Admin
Not sure how python Strings work, but the point is that since Java strings are immutable, for each asterisk, the current string is copied to a new one that is only one character longer. That means the total amount of memory allocated (though not at the same time) and copied is half the square of the final string length plus a bit of object overhead. Since chars are 2 byte, it's 2 * 16K^2 / 2 = 256M.
It takes my 2GHz Pentium 4 M about 1.6 seconds on Windows java 1.5. A modern garbage collector obviously helps a lot and 16K isn't all that big but, well, O(n^2) is O(n^2)...
Admin
Doesn't make any difference, since the length field is simply an int constant set when the String is created.
Admin
I can do it in half the number of lines.
But I suspect he might have been testing what happens when the log overflows, or maybe someone told him that writing in 16k blocks "is faster"?
Admin
And being ripped off can make people vengeful. When I quit my job in Podunkville for the gold-paved streets of Dallas (where I doubled my former income upon being hired), I naively gave the company two weeks notice and requested that my accrued vacation time, two weeks' worth, be included on my final check; I would use it to fund my move and search for work. I was informed that by resigning, I had forfeited the vacation pay. I should have taken the two weeks off first, then resigned. No amount of reasoning or appealing to higher-ups changed this.
I struggled mightily with the urge to sabotage. The two reasons why I didn't were that I'm basically a good person, and that I would need references from my former boss and coworkers.
Well, if he had "drugged" himself, it would more likely be into bed.
Admin
The forum software seems to have chopped of the
<FONT face="Courier New">String mySaboutageAttempt = "";</FONT>
somewhere earlier in this code..
Admin
(Sorry, trying again)
The forum software seems to have chopped of the
<FONT face="Courier New">String mySaboutageAttempt = "";</FONT>
somewhere earlier in this code..
Admin
Python strings are immutable objects.
No shit sherlock?
Did you remember to discount the VM's startup time?Admin
It isn't like using strlen() in C, but it isn't trivial...
My method involves the following... (assuming mySabotageAttempt reference is in local variable 1)
aload_1
invokevirtual java/lang/String/length()I
bipush 16384
if_cmplt ...
The other method involves only this... (assuming the loop count is in local variable 1)
iload_1
bipush 16384
if_cmplt ...
... iinc 1 1
Admin
I'm wrong - it is trivial. I guess it had to happen eventually :)
C:\Documents and Settings\Mike\My Documents\code\test>java -classpath . Test
Using String elapsed: 1672
Using default StringBuffer elapsed: 0
Using presized StringBuffer elapsed: 0
Using String and String.length() elapsed: 1703
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
long startTime;
long endTime;
String mySabotageAttempt;
{
System.out.print("Using String ");
startTime = System.currentTimeMillis();
mySabotageAttempt = "";
for(int i = 0; i < 16384; i++) {
mySabotageAttempt += "*";
}
endTime = System.currentTimeMillis();
System.out.println(" elapsed: " + (endTime - startTime));
}
{
System.out.print("Using default StringBuffer ");
startTime = System.currentTimeMillis();
StringBuffer mySabotageAttemptBuffer = new StringBuffer();
for(int i = 0; i < 16384; i++) {
mySabotageAttemptBuffer.append("*");
}
mySabotageAttempt = mySabotageAttemptBuffer.toString();
endTime = System.currentTimeMillis();
System.out.println(" elapsed: " + (endTime - startTime));
}
{
System.out.print("Using presized StringBuffer ");
startTime = System.currentTimeMillis();
StringBuffer mySabotageAttemptBuffer = new StringBuffer(16384);
for(int i = 0; i < 16384; i++) {
mySabotageAttemptBuffer.append("*");
}
mySabotageAttempt = mySabotageAttemptBuffer.toString();
endTime = System.currentTimeMillis();
System.out.println(" elapsed: " + (endTime - startTime));
}
{
System.out.print("Using String and String.length() ");
startTime = System.currentTimeMillis();
mySabotageAttempt = "";
while ( mySabotageAttempt.length() < 16384 ) {
mySabotageAttempt += "*";
}
endTime = System.currentTimeMillis();
System.out.println(" elapsed: " + (endTime - startTime));
}
}
}
Admin
Yes:
public class ConcatenateBenchmark
{
public static void main(String[] args)
{
long start = System.currentTimeMillis();
String mySabotageAttempt = "";
for (int i = 0; i < 16384; i++) {
mySabotageAttempt += "*";
}
System.out.println(System.currentTimeMillis()-start);
}
}
Feel free to come up with a modified version that also tries to discount JIT startup time; I can assure you that it's a negligible difference. Using the server VM it comes down to 1.4 seconds.
Admin
Yay for inlining JIT compilers!
Admin
Well, doesn't the String class have a constructor where you pass a char and an int ?
I mean, in C++ you'd do smth like :
std::string filler('*', 16384); // maybe the args are in another order
Would seem weird that Java doesn't have something similar.
Admin
uh, first off, ya, VPN might get you to remote desktop, but when the drive and the ram is full and you can't even log into the server, even getting network access from another server to delete a file is an impressive feat.
secondly "bob" was meant to represent the de-hiree, not the guy who responded to the disaster.
Admin
Just you.
Admin
This system truely hates IE 7, gotta love that embeded HTML instead of quotes - you would almost expect more out of an ASP.NET app huh?
Admin
I just thought this post looked funny with so many nested quotes, so I wanted to add another one.
Admin
It really isn't that funny. Please stop.
Admin
I totally agree. Enough is enough!
Admin
<font size="2">
</font>
<font size="2">If anyone cares:
C# under .NET 2.0 cuts that in more than half... 0.671 seconds. Unless my conversion from 100 nanoseconds to seconds is off...
</font><font size="2">static void Main(string[] args)
{
long startTicks = DateTime.Now.Ticks;
Console.WriteLine("Started @: " + startTicks);
string aReallyStupidString = "";
for (int i = 0; i < 16384; i++)
{
aReallyStupidString += "";
}
Console.WriteLine(string.Format("Took {0} secs...", (DateTime.Now.Ticks - startTicks)*.0000001));
}
</font>
Admin
Now, now folks, if we're going to horribly abuse things, we should do it in the proper Java fashiom:
final int LOG_SIZE = 16384;
String mySabotageAttempt = new String(Arrays.fill(new byte[LOG_SIZE], '*');
HTH.