- 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
What rolls with style, alone or with file?
What rolls like a resource hog?
It blows up the stack, it's great for a hack,
It's log, log, log!
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.
Admin
Goddess-damned flaky forum software...
Admin
You have a good point. The tunnel effect is pretty cool I think.
Admin
This is a highly optimised design!!! (you just have to separate out the arrays fill method because that returns void)
import java.util.Arrays;
public class wtfBenchmark {
public static void main(String[] args) {
long start = System.currentTimeMillis();
final int LOG_SIZE = 16384;
char[] stars = new char[LOG_SIZE];
Arrays.fill(stars,'*');
String mySabotageAttempt = new String(stars);
long stop = System.currentTimeMillis();
System.out.println ("Arrays Fill Method: "+(stop - start));
}
}
Admin
I thought that nothing on this site would ever really surprise me.
I was wrong.
Admin
Sorry, I won't do it agan.
Admin
Oops.
s/agan/again/
Admin
How about 'drugged himself out of bed'? I like that one better.
Admin
I've been spending some time learning java assembly language, so I decided to analyze what was going on here. It turns out that every String append causes a new StringBuffer to be created! In other words, "<font size="2">aReallyStupidString += ""</font>" becomes...
<font size="2"> ; append the ""
new java/lang/StringBuffer
dup
invokespecial java/lang/StringBuffer/<init>()V
aload 5 ; a ReallyStupidString
invokevirtual java/lang/StringBuffer/append(Ljava/lang/String;)Ljava/lang/StringBuffer;
ldc ""
invokevirtual java/lang/StringBuffer/append(Ljava/lang/String;)Ljava/lang/StringBuffer;
invokevirtual java/lang/StringBuffer/toString()Ljava/lang/String;</font>
I reimplmented it as follows, not breaking the paradigm of concatenating strings each time, but caching and reusing the StringBuffer object.
<font size="2"> ; append the "*"
aload 7 ; StringBuffer object
; initialize the StringBuffer to empty
sipush 0
invokevirtual java/lang/StringBuffer/setLength(I)V
aload 7
; now append aReallyStupidString
aload 5
invokevirtual java/lang/StringBuffer/append(Ljava/lang/String;)Ljava/lang/StringBuffer;
; and append the
ldc ""
invokevirtual java/lang/StringBuffer/append(Ljava/lang/String;)Ljava/lang/StringBuffer;
; put the result back in aReallyStupidString
invokevirtual java/lang/StringBuffer/toString()Ljava/lang/String;
astore 5</font>
That ran in less than half a second, instead of 1.6 seconds!
The WTF is that javac uses a new StringBuffer for every single '+' operation. Why not use one (or one per thread, or one per class, anything but this).
Admin
Assuming that filling the buffer is a valid solution, how about a string of \0's instead? At least it wouldn't show up in a text viewer (er, I don't think so, anyway). Idea is, pick something a little less annoying, at least. Spaces even. Eesh.
Admin
WHERE IS THE XML ???
Admin
I would've done the logging using JavaScript. Even Ajax perhaps.
Admin
No shit. He could have just used XML to format the log lines, and wouldn't have needed 16384 *'s.
vc
Admin
I would have created 16384 div elements, and appended those to a document, giving them all a text node to chew on, and filling that text node with, you guessed it, '*'.
Admin
You just can't help yourself, can you!
Admin
You raise a good point. I will correct my mistake post haste.
import org.xml.sax.helpers.DefaultHandler;
import java.util.Arrays;
public class wtfBenchmarkXML extends DefaultHandler{
private StringBuffer strBuffer = new StringBuffer();
public String myFillerCharInStringFormat = null;
public wtfBenchmarkXML(){
super();
}
public static void main(String[] args) throws Exception{ //Top Level Exception Handling!!!
XMLReader xml= XMLReaderFactory.createXMLReader(); // Look MA! XML!
wtfBenchmarkXML me= new wtfBenchmarkXML(); //This is me, I implement XML.
xml.setContentHandler(me); // I handle all of the content
xml.setErrorHandler(me); // I also handle all of the errors
FileReader r = new FileReader("myxmlconfigfile.xml"); //maybe this should change to use a command line arg?
xml.parse(new InputSource(r)); //Finally.... XML!
long start = System.currentTimeMillis(); // its not fair to time the xml loading so we will just start timing here.
final int LOG_SIZE = 16384;
char[] stars = new char[LOG_SIZE];
Arrays.fill(stars,me.myFillerCharInStringFormat.charAt(0));
String mySabotageAttempt = new String(stars);
long stop = System.currentTimeMillis();
System.out.println ("Arrays Fill Method: "+(stop - start));
}
public void startElement (String uri, String name, String qName, Attributes atts) {
if (name.equalsIgnoreCase("LogFillerChar"){
strBuffer = new StringBuffer();
}
}
public void endElement (String uri, String name, String qName){
if (name.equalsIgnoreCase("LogFillerChar"){
myFillerCharInStringFormat = strBuffer.toString();
}
}
public void characters (char ch[], int start, int length) {
strBuffer.append(ch,start,length);
}
}
*******************
Then... all we need is an XML file named "myxmlconfigfile.xml" with contents like this:
Viola .... XML. Any questions?
Admin
Just cut it out! All of you!
Admin
It is sort of getting on my nerves, too.
Admin
I tried to quote all 12 of you nitwits, but the forum software choked! "Non-matching quote blocks in post..." (I counted the quote blocks and they did, in fact, match.)
Can't really say I'm surprised. I am surprised that it successfully dealt with 12 levels of nesting as it is.
Admin
Yes, you could eaily do that: http://today.java.net/pub/a/today/2005/12/13/log4ajax.html
Admin
Python strings are immutable as well (as someone else pointed out). However python uses reference counting for garbage collection, while Java uses true garbage collection. In general the Java way is better, but in this once case Python will use much less memory along the way because it will free each string as soon as it is done with it, while Java may keep them all around if the garbage collector doesn't get around to running, even if the garabage collector does run, it will be more memory in use along the way. If you have less than 256M RAM, python will not hit swap (nor an out of memory error), while there is a tiny tiny chance that Java will.
Of course this is only a theoretical problem.
Admin
Might be too late now, but check the local employment laws. In many areas vacation is earned and must be paid out. When I quit (several jobs ago), my last check was not only for my last two weeks, but also the week vacation that I had earned, but not yet taken.
Note that sick leave (often called paid time off) does not follow under the same rules. However if a company gives only PTO instead of vacation courts of decided that it really is vacation and forced the company to pay off on it.
I'm not an expert on employment law. You might find it worthwhile to become an expert. Or at least see a lawyer. Though of course if you go to court over the issue, you loose your former boss as a reference. (Though most bosses are going to "He worked from date to date, as a title, I'm not allowed to say anything more")
Admin
What is Python's technique for dealing with circular references? Does Python occassionally do a Mark/Sweep or a Copy collection as well?
Admin
"Probably because testing consisted of a run over a short timescale, and no one cared if the log was on the order of a megabyte during testing."
I guess no one (other than the original programmer) looked at the log. Looking at the log would have been a "test" that would have caught this nonsense very early.
Admin
Wow, I've never seen nested quotes this deep before.
Anybody else interested in knowing what the limit is to nested quotes?
I encourage everybody to keep quoting this. Let's call it "WTB Quote Boundary Testing" [:D]
Admin
Meaning they knew this code existed and what it would do, fired him for it, implemented it anyway, then panicked when it broke? That'd be a WTF all to itself.
Admin
Wierd, sometimes i get the error, sometimes not... i think this is 14.
Admin
WTF... we are at the limit now I think... scroll up and see how the oldest quote entry gets truncated. harmmmf.
Admin
Hah! Not a forum limitation after all. Appears to be a browser (Firefox) limitation. Happy day, I learned something new.
Admin
Do you realize that, after a few quotes, this starts to take the shape of an ancient Aztec step-pyramid?
Admin
How utterly inefficient.
String bomb = "*";
while(bomb.length() < 16384) bomb += bomb;
-Me
Admin
These posts have disappeared beyond the event horizon and are now collapsed into a singularity of bytecode.
Admin
Are you here?
Admin
The word you're looking for is "ziggurat".
ok
dpm
Admin
Usually with a language that supports opening a file for write with the O_SYNC flag ;) It would also be helpful to make sure that the filesystem supports this too.
Of course, you ought to ask yourself why it matters that the logs are synced. If it's in case the machine crashes, then it might be more appropriate to write the logs to another machine (or several).
Admin
weeeee!
Admin
Ziggurat? I knew that! [:^)]
Admin
Too bad... the code snipped above is actually rendered as an
image, not text. I tried to copy & paste this wonderful piece of
code to use it in my own logging library, alas... ;-)
Admin
A second app made sure the first app was running by reading the log!
Admin
Admin
That's calling bomb.length() more times than necessary.
String bomb = "*"; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb; bomb += bomb;
That should run faster.