diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py
index 57bb63e..9cbd8b0 100644
--- a/django/core/cache/backends/filebased.py
+++ b/django/core/cache/backends/filebased.py
@@ -4,6 +4,7 @@ import hashlib
 import os
 import shutil
 import time
+import random
 try:
     import cPickle as pickle
 except ImportError:
@@ -113,20 +114,23 @@ class FileBasedCache(BaseCache):
             return
 
         try:
-            filelist = sorted(os.listdir(self._dir))
+            filelist = os.listdir(self._dir)
         except (IOError, OSError):
             return
 
         if self._cull_frequency == 0:
-            doomed = filelist
-        else:
-            doomed = [os.path.join(self._dir, k) for (i, k) in enumerate(filelist) if i % self._cull_frequency == 0]
+            self.clear()
+            return
+
+        ranno = random.randint(0, self._cull_frequency)
+        doomed = [
+            os.path.join(self._dir, k)
+            for (i, k) in enumerate(filelist)
+            if i % self._cull_frequency == ranno]
 
         for topdir in doomed:
             try:
-                for root, _, files in os.walk(topdir):
-                    for f in files:
-                        self._delete(os.path.join(root, f))
+                shutil.rmtree(topdir)
             except (IOError, OSError):
                 pass
 
diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
index c5349d5..a0acb75 100644
--- a/tests/regressiontests/cache/tests.py
+++ b/tests/regressiontests/cache/tests.py
@@ -408,17 +408,20 @@ class BaseCacheTests(object):
         self.assertEqual(self.cache.get('key3'), 'sausage')
         self.assertEqual(self.cache.get('key4'), 'lobster bisque')
 
-    def perform_cull_test(self, initial_count, final_count):
+    def perform_cull_test(self, initial_count, final_count, cache=None):
         """This is implemented as a utility method, because only some of the backends
         implement culling. The culling algorithm also varies slightly, so the final
         number of entries will vary between backends"""
+        if cache is None:
+            cache = self.cache
+
         # Create initial cache key entries. This will overflow the cache, causing a cull
         for i in range(1, initial_count):
-            self.cache.set('cull%d' % i, 'value', 1000)
+            cache.set('cull-%d' % i, 'value', 1000)
         count = 0
         # Count how many keys are left in the cache.
         for i in range(1, initial_count):
-            if self.cache.has_key('cull%d' % i):
+            if cache.has_key('cull-%d' % i):
                 count = count + 1
         self.assertEqual(count, final_count)
 
@@ -848,6 +851,9 @@ class FileBasedCacheTests(unittest.TestCase, BaseCacheTests):
     def setUp(self):
         self.dirname = tempfile.mkdtemp()
         self.cache = get_cache(self.backend_name, LOCATION=self.dirname, OPTIONS={'MAX_ENTRIES': 30})
+        self.full_cull_cache = get_cache(self.backend_name,
+                LOCATION=self.dirname,
+                OPTIONS={'MAX_ENTRIES': 30, 'CULL_FREQUENCY': 0})
         self.prefix_cache = get_cache(self.backend_name, LOCATION=self.dirname, KEY_PREFIX='cacheprefix')
         self.v2_cache = get_cache(self.backend_name, LOCATION=self.dirname, VERSION=2)
         self.custom_key_cache = get_cache(self.backend_name, LOCATION=self.dirname, KEY_FUNCTION=custom_key_func)
@@ -879,12 +885,15 @@ class FileBasedCacheTests(unittest.TestCase, BaseCacheTests):
         self.assertTrue(not os.path.exists(os.path.dirname(keypath)))
         self.assertTrue(not os.path.exists(os.path.dirname(os.path.dirname(keypath))))
 
+    def test_full_cull(self):
+        self.perform_cull_test(32, 1, self.full_cull_cache)
+
     def test_cull(self):
-        self.perform_cull_test(50, 29)
+        self.perform_cull_test(35, 24)
 
     def test_old_initialization(self):
         self.cache = get_cache('file://%s?max_entries=30' % self.dirname)
-        self.perform_cull_test(50, 29)
+        self.perform_cull_test(35, 24)
 
 class CustomCacheKeyValidationTests(unittest.TestCase):
     """
