Index: components/select.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/select.inc,v
retrieving revision 1.22.2.29
diff -u -p -r1.22.2.29 select.inc
--- components/select.inc	4 Mar 2009 05:05:11 -0000	1.22.2.29
+++ components/select.inc	5 Apr 2009 21:03:47 -0000
@@ -485,38 +485,58 @@ function _webform_csv_data_select($data,
  *   Optional. If specified, return the option array and exclude any optgroups.
  */
 function _webform_select_options($text, $flat = FALSE) {
-  $options = array();
-  $rows = array_filter(explode("\n", trim($text)));
-  $group = NULL;
-  foreach ($rows as $option) {
-    $option = trim($option);
-    /**
-     * If the Key of the option is within < >, treat as an optgroup
-     *
-     * <Group 1>
-     *   creates an optgroup with the label "Group 1"
-     *
-     * <>
-     *   Unsets the current group, allowing items to be inserted at the root element.
-     */
+  static $all_options;
+  if (!is_array($all_options)) {
+    $all_options = array();
+    $all_options[TRUE] = array();
+    $all_options[FALSE] = array();
+  }
+  
+  // See if the options block has been processed before. We'll keep each
+  // processed option block in a global array indexed by the MD5 hash of the
+  // text and the $flat value
+  $m = md5($text);
+  // processed options block does not already exist, so generate it
+  if (!isset($all_options[$flat][$m])) {
+    $options = array();
+    $rows = array_filter(explode("\n", trim($text)));
+    $group = NULL;
+    foreach ($rows as $option) {
+      $option = trim($option);
+      /**
+       * If the Key of the option is within < >, treat as an optgroup
+       *
+       * <Group 1>
+       *   creates an optgroup with the label "Group 1"
+       *
+       * <>
+       *   Unsets the current group, allowing items to be inserted at the root element.
+       */
 
-    if (preg_match('/^\<([^>]*)\>$/', $option, $matches)) {
-      if (empty($matches[1])) {
-        unset($group);
+      if (preg_match('/^\<([^>]*)\>$/', $option, $matches)) {
+        if (empty($matches[1])) {
+          unset($group);
+        }
+        elseif (!$flat) {
+          $group = _webform_filter_values($matches[1], NULL, NULL, FALSE);
+        }
       }
-      elseif (!$flat) {
-        $group = _webform_filter_values($matches[1], NULL, NULL, FALSE);
+      elseif (preg_match('/^([^|]+)\|(.*)$/', $option, $matches)) {
+        $key = _webform_filter_values($matches[1], NULL, NULL, FALSE);
+        $value = _webform_filter_values($matches[2], NULL, NULL, FALSE);
+        isset($group) ? $options[$group][$key] = $value : $options[$key] = $value;
+      }
+      else {
+        $filtered_option = _webform_filter_values($option, NULL, NULL, FALSE);
+        isset($group) ? $options[$group][$filtered_option] = $filtered_option : $options[$filtered_option] = $filtered_option;
       }
     }
-    elseif (preg_match('/^([^|]+)\|(.*)$/', $option, $matches)) {
-      $key = _webform_filter_values($matches[1], NULL, NULL, FALSE);
-      $value = _webform_filter_values($matches[2], NULL, NULL, FALSE);
-      isset($group) ? $options[$group][$key] = $value : $options[$key] = $value;
-    }
-    else {
-      $filtered_option = _webform_filter_values($option, NULL, NULL, FALSE);
-      isset($group) ? $options[$group][$filtered_option] = $filtered_option : $options[$filtered_option] = $filtered_option;
-    }
+    $all_options[$flat][$m] = $options;
+  }
+  // option block already existed
+  else {
+    // do nothing
   }
-  return $options;
+  // return the cached options block
+  return $all_options[$flat][$m];
 }
