CodeSOD: The Monthly Report
"Karen, you need to run the monthly report while Ivan is on vacation," Bruno asked.
"Wait, isn't that just a scheduled job?"
"No. It's old code, and we don't trust the scheduling systems, and if anything goes wrong how do we know and""
"Well, I guess I can run it, then," Karen said.
"Great, you'll need to restore the financials database from backup onto your local instance, then run the reporting tool in local configuration-"
"Wait" why?"
"Why? It's too heavy a job for our production server!"
Karen followed the instructions. She spent a few hours waiting for the database to restore to her local developer instance. She fired off the job and waited another few hours while it ground away doing whatever it was doing. Finally, it quit, leaving behind a 40MB CSV file as its monthly report.
At this point, Karen wondered- why did that take so long?. Curious, she extracted all the SQL queries and profiled them. They ran in seconds, and unless there was a poorly designed loop she hadn't noticed, it wasn't the queries that were making it slow. Her next guess was that it was the file IO that was slow- but how could that be? How hard was it to write a string of text to a file?
Private Sub writetopath(ByVal inputstring As String, ByVal myfilepath As String) Try Dim myStreamWriter2 As System.IO.StreamWriter myStreamWriter = System.IO.File.CreateText(logfilename2) myStreamWriter2 = System.IO.File.AppendText(myfilepath) myStreamWriter2.WriteLine(inputstring) myStreamWriter2.Flush() myStreamWriter2.Dispose() Catch ex As Exception Label5.Text = "Problem while writting to file: " & ex.Message Label5.BackColor = System.Drawing.ColorTranslator.FromHtml("#ff3c3c") writetofulllog("Error at sub writetopath. " & Label5.Text) 'MessageBox.Show(Label5.Text) End Try End Sub ' Sub writetopath
The original developer had obviously taken the advice "close your file handles" to heart, because this function was called for every line the program output. That means for every line in the 40MB file (each line about 40 characters long) it had to construct a StreamWriter instance, write a line to its buffer, flush its buffer, and dispose of the instance.
Karen spent five minutes to refactor the program. Afterwards, it ran in less than a minute. She still couldn't convince Bruno to let her schedule it, but at least she didn't need to restore the entire database before running it.
[Advertisement] Application Release Automation for DevOps - integrating with best of breed development tools. Free for teams with up to 5 users. Download and learn more today!