In order to debug we usually write chunks of data to the debug log using System.debug statements. Will writing too many debug logs affect visualforce page or Apex performance in any way?
I created the simplest page in the world, with a custom controller, that looked like this:
And in the controller I simply had
I loaded this page up and inspected the source for the generation time, which is in a HTML comment at the bottom:
Here we see the simple page took 80ms.
I loaded it 10 times and took an average of the load times, it was 78ms.
I then added System.debug to the for loop
and loaded the page 10 more times.
I averaged it out and the page now took 4140ms !!
I also then opened the developer console and checked, there were a bunch of 1.72Mb log files, so it was doing what one might expect, and the logging (allbeit 100,000 of them) was significantly slowing down the page load.
I then took the debug out of the loop (but left the empty loop as per the control) and added a single debug statement with a 3,500 character string in it. The average load for this page was 86ms indicating a single long debug statement does also slow the page.
(after this I was going to go on to a couple of other tests, but when I returned to the control state, I quickly re-tested my base level and they were up into the 100's of ms so I think either my DE on eu2 was being hammered, or I had simply worn a bit of it out temporarily! Therefore no future results would be fair ;) )
Following other answers surrounding making the debug optional based on a boolean switch, I changed the controller to be this and ran the test again (I also re-ran my control a couple of times and the org was back on 75 - 85ms for standard page load)
The page load time was now an average (just 5 runs this time) of 112ms so the boolean flag does make a big difference. Putting that into a custom setting/label etc. and pumping it into the controller etc. might slow you down, but the concept of switchable logging has potential! (I was suspicious, so I changed the flag to true and loaded the page, low and behold, 4 seconds).
Building on top of Simon's answer, if a page loads on average in 78ms with no debug statements but loads on average at 4140ms with 100,000 debug statements, we could determine:
Now, these are obviously the most simple debug statements you would ever use. If they were longer, it would be safe to say the time it takes to log these debug statements may increase. For the sake of argument, let's say a debug statement averages 5x as long as the simplest debug statement. In that scenario, we are looking at .2031ms. Let's go a step further and say it is 10x the simplest debug statement, even then we are only looking at .4062ms.
At 10x the simplest debug statement for the average debug statement, we can log 2461 statements and still only effect the page by slightly under a second (999.65ms). While it does effect performance, I think it is safe to use them in most circumstances, given that you most likely won't be running thousands of debug statements. Be smart and keep them out of loops, etc and you should be fine to debug the information you need with a minimal effect on performance.
To be clear, this isn't to say you should put thousands of debug statements in your code. As sfdcfox noted in a comment on Simon's answer, on performance critical pages being able to shave a few milliseconds add up to increase performance.
All I am saying by this is that if you have a troublesome page that you need to put a few debug statements in, it isn't the end of the world. If a page takes 1 second to load without debug statements, a few debug statements won't add more than a few milliseconds. Will a user really notice the difference between a 1 second page load and a 1.05 second page load? I would argue they wouldn't.
What you are really asking is,
How can I have debug statements in my code for future debugging without affecting current performance excessively?
I suggest structuring your debug calls like this:
where DebugOn is a static class variable. For extra convenience, DebugOn could load its value from a Custom Label. That way, you can turn logging on without changing your code. As suggested in other answers, keeping logging out of loops will help avoid performance issues.