Last week when I dug into the details of the special permission optimization, we saw in the code that before the CLR can use this optimized form of a demand, it needs to check to ensure there are no Deny or PermitOnly modifiers on the call stack. I noted in the post that it’s yet another reason to avoid using these operations, since checking a bit mask on the AppDomain is obviously much faster than crawling the call stack and checking the frames of each method found.
That example helps to illustrate a general principal: any optimizations that the security system (and code in general) can make based upon static state will be disabled by the introduction of dynamic state. In this case, at load time we can note what the permission sets of the AppDomain and each assembly are. Since those permission sets are guaranteed never to change, we can optimize based upon that information. However, when dynamic state comes along -- in this case stack walk modifiers which can be added and removed as frequently as the application wants at runtime -- we can no longer use that information.
… so to reiterate a point which may have gotten lost in the technical details last week. This is yet another reason why Deny and PermitOnly should be avoided whenever and wherever possible in your code.