diff -ru nagios-3.2.0/base/utils.c nagios-3.2.0.new/base/utils.c
--- nagios-3.2.0/base/utils.c	2009-08-11 16:53:04.000000000 +0000
+++ nagios-3.2.0.new/base/utils.c	2009-12-22 22:54:42.000000000 +0000
@@ -3457,8 +3457,8 @@
         }
 
 
-/* gets one line of input from an mmap()'ed file */
-char *mmap_fgets(mmapfile *temp_mmapfile){
+/* gets one line of input from an mmap()'ed file, reusing line buffer */
+char *mmap_fgets_buf(mmapfile *temp_mmapfile, char **oldbuf, int *oldsize){
 	char *buf=NULL;
 	unsigned long x=0L;
 	int len=0;
@@ -3486,7 +3486,23 @@
 	len=(int)(x-temp_mmapfile->current_position);
 
 	/* allocate memory for the new line */
-	if((buf=(char *)malloc(len+1))==NULL)
+	if(oldbuf && *oldbuf && oldsize && *oldsize){
+		if(*oldsize < len+1){
+			*oldbuf=buf=(char *)realloc(*oldbuf,len+1);
+			if (!buf)
+				*oldsize=0;
+			}
+		else
+			buf=*oldbuf;
+	}
+	else{
+		buf=(char *)malloc(len+1);
+		if(oldbuf && oldsize){
+			*oldbuf=buf;
+			*oldsize=buf?(len+1):0;
+			}
+		}
+	if(!buf)
 		return NULL;
 
 	/* copy string to newly allocated memory and terminate the string */
@@ -3502,6 +3518,11 @@
 	return buf;
         }
 
+/* gets one line of input from an mmap()'ed file */
+char *mmap_fgets(mmapfile *temp_mmapfile){
+	return mmap_fgets_buf(temp_mmapfile, NULL, NULL);
+        }
+
 
 
 /* gets one line of input from an mmap()'ed file (may be contained on more than one line in the source file) */
diff -ru nagios-3.2.0/cgi/cgiutils.c nagios-3.2.0.new/cgi/cgiutils.c
--- nagios-3.2.0/cgi/cgiutils.c	2009-07-31 16:54:20.000000000 +0000
+++ nagios-3.2.0.new/cgi/cgiutils.c	2009-12-22 22:57:40.000000000 +0000
@@ -1209,8 +1209,8 @@
 
 
 
-/* gets one line of input from an mmap()'ed file */
-char *mmap_fgets(mmapfile *temp_mmapfile){
+/* gets one line of input from an mmap()'ed file, reusing line buffer */
+char *mmap_fgets_buf(mmapfile *temp_mmapfile, char **oldbuf, int *oldsize){
 	char *buf=NULL;
 	unsigned long x=0L;
 	int len=0;
@@ -1238,7 +1238,23 @@
 	len=(int)(x-temp_mmapfile->current_position);
 
 	/* allocate memory for the new line */
-	if((buf=(char *)malloc(len+1))==NULL)
+	if(oldbuf && *oldbuf && oldsize && *oldsize){
+		if(*oldsize < len+1){
+			*oldbuf=buf=(char *)realloc(*oldbuf,len+1);
+			if (!buf)
+				*oldsize=0;
+			}
+		else
+			buf=*oldbuf;
+	}
+	else{
+		buf=(char *)malloc(len+1);
+		if(oldbuf && oldsize){
+			*oldbuf=buf;
+			*oldsize=buf?(len+1):0;
+			}
+		}
+	if(!buf)
 		return NULL;
 
 	/* copy string to newly allocated memory and terminate the string */
@@ -1254,6 +1270,11 @@
 	return buf;
         }
 
+/* gets one line of input from an mmap()'ed file */
+char *mmap_fgets(mmapfile *temp_mmapfile){
+	return mmap_fgets_buf(temp_mmapfile, NULL, NULL);
+        }
+
 
 
 /* gets one line of input from an mmap()'ed file (may be contained on more than one line in the source file) */
diff -ru nagios-3.2.0/common/comments.c nagios-3.2.0.new/common/comments.c
--- nagios-3.2.0/common/comments.c	2008-11-30 17:22:58.000000000 +0000
+++ nagios-3.2.0.new/common/comments.c	2009-12-23 01:33:22.000000000 +0000
@@ -44,6 +44,8 @@
 
 
 comment     *comment_list=NULL;
+int	    defer_comment_sorting = 0;
+static int  unsorted_comments = 0;
 comment     **comment_hashlist=NULL;
 
 
@@ -503,28 +505,35 @@
 		return ERROR;
 	        }
 
-	/* add new comment to comment list, sorted by comment id */
-	last_comment=comment_list;
-	for(temp_comment=comment_list;temp_comment!=NULL;temp_comment=temp_comment->next){
-		if(new_comment->comment_id<temp_comment->comment_id){
-			new_comment->next=temp_comment;
-			if(temp_comment==comment_list)
-				comment_list=new_comment;
-			else
-				last_comment->next=new_comment;
-			break;
-		        }
-		else
-			last_comment=temp_comment;
-	        }
-	if(comment_list==NULL){
-		new_comment->next=NULL;
+	if(defer_comment_sorting){
+		new_comment->next=comment_list;
 		comment_list=new_comment;
-	        }
-	else if(temp_comment==NULL){
-		new_comment->next=NULL;
-		last_comment->next=new_comment;
-	        }
+		unsorted_comments++;
+		}
+	else{
+		/* add new comment to comment list, sorted by comment id */
+		last_comment=comment_list;
+		for(temp_comment=comment_list;temp_comment!=NULL;temp_comment=temp_comment->next){
+			if(new_comment->comment_id<temp_comment->comment_id){
+				new_comment->next=temp_comment;
+				if(temp_comment==comment_list)
+					comment_list=new_comment;
+				else
+					last_comment->next=new_comment;
+				break;
+				}
+			else
+				last_comment=temp_comment;
+			}
+		if(comment_list==NULL){
+			new_comment->next=NULL;
+			comment_list=new_comment;
+			}
+		else if(temp_comment==NULL){
+			new_comment->next=NULL;
+			last_comment->next=new_comment;
+			}
+		}
 
 #ifdef NSCORE
 #ifdef USE_EVENT_BROKER
@@ -536,8 +545,43 @@
 	return OK;
         }
 
+static int comment_compar(const void *p1, const void *p2){
+	comment *c1 = *(comment **)p1;
+	comment *c2 = *(comment **)p2;
+	return (c1->comment_id < c2->comment_id) ? -1 : (c1->comment_id - c2->comment_id);
+	}
+
+int sort_comments(void){
+	comment **array, *last_comment;
+	int i = 0;
+
+	if(!defer_comment_sorting)
+		return OK;
+	defer_comment_sorting=0;
 
+	if(!unsorted_comments)
+		return OK;
 
+	if(!(array=malloc(sizeof(*array)*unsorted_comments)))
+		return ERROR;
+	while(comment_list && i<unsorted_comments){
+		array[i++]=comment_list;
+		comment_list=comment_list->next;
+	}
+	if (comment_list || i<unsorted_comments)
+		return ERROR;
+
+	qsort((void *)array, i, sizeof(*array), comment_compar);
+	comment_list = last_comment = array[0];
+	for (i=1; i<unsorted_comments;i++){
+		last_comment->next = array[i];
+		last_comment = last_comment->next;
+		}
+	last_comment->next = NULL;
+	my_free(array);
+	unsorted_comments = 0;
+	return OK;
+	}
 
 /******************************************************************/
 /********************* CLEANUP FUNCTIONS **************************/
diff -ru nagios-3.2.0/common/downtime.c nagios-3.2.0.new/common/downtime.c
--- nagios-3.2.0/common/downtime.c	2008-11-30 17:22:58.000000000 +0000
+++ nagios-3.2.0.new/common/downtime.c	2009-12-23 01:37:33.000000000 +0000
@@ -46,6 +46,8 @@
 
 
 scheduled_downtime *scheduled_downtime_list=NULL;
+int		   defer_downtime_sorting = 0;
+static int	   unsorted_downtime = 0;
 
 #ifdef NSCORE
 extern timed_event *event_list_high;
@@ -931,29 +933,35 @@
 	new_downtime->incremented_pending_downtime=FALSE;
 #endif
 
-	/* add new downtime to downtime list, sorted by start time */
-	last_downtime=scheduled_downtime_list;
-	for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){
-		if(new_downtime->start_time<temp_downtime->start_time){
-			new_downtime->next=temp_downtime;
-			if(temp_downtime==scheduled_downtime_list)
-				scheduled_downtime_list=new_downtime;
-			else
-				last_downtime->next=new_downtime;
-			break;
-		        }
-		else
-			last_downtime=temp_downtime;
-	        }
-	if(scheduled_downtime_list==NULL){
-		new_downtime->next=NULL;
+	if(defer_downtime_sorting){
+		new_downtime->next=scheduled_downtime_list;
 		scheduled_downtime_list=new_downtime;
-	        }
-	else if(temp_downtime==NULL){
-		new_downtime->next=NULL;
-		last_downtime->next=new_downtime;
-	        }
-
+		unsorted_downtime++;
+	}
+	else{
+		/* add new downtime to downtime list, sorted by start time */
+		last_downtime=scheduled_downtime_list;
+		for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){
+			if(new_downtime->start_time<temp_downtime->start_time){
+				new_downtime->next=temp_downtime;
+				if(temp_downtime==scheduled_downtime_list)
+					scheduled_downtime_list=new_downtime;
+				else
+					last_downtime->next=new_downtime;
+				break;
+				}
+			else
+				last_downtime=temp_downtime;
+			}
+		if(scheduled_downtime_list==NULL){
+			new_downtime->next=NULL;
+			scheduled_downtime_list=new_downtime;
+			}
+		else if(temp_downtime==NULL){
+			new_downtime->next=NULL;
+			last_downtime->next=new_downtime;
+			}
+		}
 #ifdef NSCORE
 #ifdef USE_EVENT_BROKER
 	/* send data to event broker */
@@ -964,6 +972,43 @@
 	return OK;
         }
 
+static int downtime_compar(const void *p1, const void *p2){
+	scheduled_downtime *d1 = *(scheduled_downtime **)p1;
+	scheduled_downtime *d2 = *(scheduled_downtime **)p2;
+	return (d1->start_time < d2->start_time) ? -1 : (d1->start_time - d2->start_time);
+	}
+
+int sort_downtime(void){
+	scheduled_downtime **array, *last_downtime;
+	int i = 0;
+
+	if(!defer_downtime_sorting)
+		return OK;
+	defer_downtime_sorting=0;
+
+	if(!unsorted_downtime)
+		return OK;
+
+	if(!(array=malloc(sizeof(*array)*unsorted_downtime)))
+		return ERROR;
+	while(scheduled_downtime_list && i<unsorted_downtime){
+		array[i++]=scheduled_downtime_list;
+		scheduled_downtime_list=scheduled_downtime_list->next;
+	}
+	if (scheduled_downtime_list || i<unsorted_downtime)
+		return ERROR;
+
+	qsort((void *)array, i, sizeof(*array), downtime_compar);
+	scheduled_downtime_list = last_downtime = array[0];
+	for (i=1; i<unsorted_downtime;i++){
+		last_downtime->next = array[i];
+		last_downtime = last_downtime->next;
+		}
+	last_downtime->next = NULL;
+	my_free(array);
+	unsorted_downtime = 0;
+	return OK;
+	}
 
 
 
diff -ru nagios-3.2.0/include/comments.h nagios-3.2.0.new/include/comments.h
--- nagios-3.2.0/include/comments.h	2008-11-30 17:22:59.000000000 +0000
+++ nagios-3.2.0.new/include/comments.h	2009-12-23 01:39:31.000000000 +0000
@@ -112,7 +112,13 @@
 int number_of_host_comments(char *);			              /* returns the number of comments associated with a particular host */
 int number_of_service_comments(char *, char *);		              /* returns the number of comments associated with a particular service */
 
+/* If you are going to be adding a lot of comments in sequence, set
+   defer_comment_sorting to 1 before you start and then call
+   sort_comments afterwards. Things will go MUCH faster. */
+
+extern int defer_comment_sorting;
 int add_comment(int,int,char *,char *,time_t,char *,char *,unsigned long,int,int,time_t,int);      /* adds a comment (host or service) */
+int sort_comments(void);
 int add_host_comment(int,char *,time_t,char *,char *,unsigned long,int,int,time_t,int);            /* adds a host comment */
 int add_service_comment(int,char *,char *,time_t,char *,char *,unsigned long,int,int,time_t,int);  /* adds a service comment */
 
diff -ru nagios-3.2.0/include/downtime.h nagios-3.2.0.new/include/downtime.h
--- nagios-3.2.0/include/downtime.h	2008-11-30 17:22:59.000000000 +0000
+++ nagios-3.2.0.new/include/downtime.h	2009-12-23 01:39:48.000000000 +0000
@@ -86,7 +86,14 @@
 
 int add_host_downtime(char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long);
 int add_service_downtime(char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long);
+
+/* If you are going to be adding a lot of downtime in sequence, set
+   defer_downtime_sorting to 1 before you start and then call
+   sort_downtime afterwards. Things will go MUCH faster. */
+
+extern int defer_downtime_sorting;
 int add_downtime(int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long);
+int sort_downtime(void);
 
 scheduled_downtime *find_downtime(int,unsigned long);
 scheduled_downtime *find_host_downtime(unsigned long);
diff -ru nagios-3.2.0/include/nagios.h nagios-3.2.0.new/include/nagios.h
--- nagios-3.2.0/include/nagios.h	2008-12-14 14:52:23.000000000 +0000
+++ nagios-3.2.0.new/include/nagios.h	2009-12-22 22:52:45.000000000 +0000
@@ -811,6 +811,7 @@
 mmapfile *mmap_fopen(char *);				/* open a file read-only via mmap() */
 int mmap_fclose(mmapfile *);
 char *mmap_fgets(mmapfile *);
+char *mmap_fgets_buf(mmapfile *, char **, int *);
 char *mmap_fgets_multiline(mmapfile *);
 
 
diff -ru nagios-3.2.0/xdata/xsddefault.c nagios-3.2.0.new/xdata/xsddefault.c
--- nagios-3.2.0/xdata/xsddefault.c	2009-07-31 15:06:49.000000000 +0000
+++ nagios-3.2.0.new/xdata/xsddefault.c	2009-12-23 01:37:11.000000000 +0000
@@ -738,6 +738,7 @@
 	FILE *fp=NULL;
 #else
 	char *input=NULL;
+	int inputsize = 0;
 	mmapfile *thefile=NULL;
 #endif
 	int data_type=XSDDEFAULT_NO_DATA;
@@ -766,7 +767,7 @@
 	unsigned long triggered_by=0;
 	unsigned long duration=0L;
 	int x=0;
-
+	int in_block=FALSE;
 
 	/* initialize some vars */
 	for(x=0;x<MAX_CHECK_STATS_TYPES;x++){
@@ -789,6 +790,8 @@
 		return ERROR;
 #endif
 
+	defer_downtime_sorting = defer_comment_sorting = 1;
+
 	/* read all lines in the status file */
 	while(1){
 
@@ -797,11 +800,8 @@
 		if(fgets(input,sizeof(input),fp)==NULL)
 			break;
 #else
-		/* free memory */
-		my_free(input);
-
 		/* read the next line */
-		if((input=mmap_fgets(thefile))==NULL)
+		if((input=mmap_fgets_buf(thefile, &input, &inputsize))==NULL)
 			break;
 #endif
 
@@ -811,11 +811,15 @@
 		if(input[0]=='#' || input[0]=='\x0')
 			continue;
 
-		else if(!strcmp(input,"info {"))
+		else if(!(in_block || strcmp(input,"info {"))){
 			data_type=XSDDEFAULT_INFO_DATA;
-		else if(!strcmp(input,"programstatus {"))
+			in_block=TRUE;
+			}
+		else if(!(in_block || strcmp(input,"programstatus {"))){
 			data_type=XSDDEFAULT_PROGRAMSTATUS_DATA;
-		else if(!strcmp(input,"hoststatus {")){
+			in_block=TRUE;
+			}
+		else if(!(in_block || strcmp(input,"hoststatus {"))){
 			data_type=XSDDEFAULT_HOSTSTATUS_DATA;
 			temp_hoststatus=(hoststatus *)malloc(sizeof(hoststatus));
 			if(temp_hoststatus){
@@ -825,8 +829,9 @@
 				temp_hoststatus->perf_data=NULL;
 				temp_hoststatus->check_options=0;
 			        }
+			in_block=TRUE;
 		        }
-		else if(!strcmp(input,"servicestatus {")){
+		else if(!(in_block || strcmp(input,"servicestatus {"))){
 			data_type=XSDDEFAULT_SERVICESTATUS_DATA;
 			temp_servicestatus=(servicestatus *)malloc(sizeof(servicestatus));
 			if(temp_servicestatus){
@@ -837,19 +842,31 @@
 				temp_servicestatus->perf_data=NULL;
 				temp_servicestatus->check_options=0;
 			        }
+			in_block=TRUE;
 		        }
-		else if(!strcmp(input,"contactstatus {")){
+		else if(!(in_block || strcmp(input,"contactstatus {"))){
 			data_type=XSDDEFAULT_CONTACTSTATUS_DATA;
+			in_block=TRUE;
 			/* unimplemented */
 		        }
-		else if(!strcmp(input,"hostcomment {"))
+		else if(!(in_block || strcmp(input,"hostcomment {"))){
 			data_type=XSDDEFAULT_HOSTCOMMENT_DATA;
-		else if(!strcmp(input,"servicecomment {"))
+			in_block=TRUE;
+			}
+		else if(!(in_block || strcmp(input,"servicecomment {"))){
 			data_type=XSDDEFAULT_SERVICECOMMENT_DATA;
-		else if(!strcmp(input,"hostdowntime {"))
+			in_block=TRUE;
+			}
+		else if(!(in_block || strcmp(input,"hostdowntime {"))){
 			data_type=XSDDEFAULT_HOSTDOWNTIME_DATA;
-		else if(!strcmp(input,"servicedowntime {"))
+			in_block=TRUE;
+		}
+		else if(!(in_block || strcmp(input,"servicedowntime {"))){
 			data_type=XSDDEFAULT_SERVICEDOWNTIME_DATA;
+			in_block=TRUE;
+			}
+		else if(*input && input[strlen(input)-1]=='{')
+			in_block=TRUE;
 
 		else if(!strcmp(input,"}")){
 
@@ -929,6 +946,7 @@
 			        }
 
 			data_type=XSDDEFAULT_NO_DATA;
+			in_block=FALSE;
 		        }
 
 		else if(data_type!=XSDDEFAULT_NO_DATA){
@@ -1301,11 +1319,15 @@
 	my_free(input);
 	mmap_fclose(thefile);
 #endif
-
 	/* free memory */
 	my_free(xsddefault_status_log);
 	my_free(xsddefault_temp_file);
 
+	if(sort_downtime()!=OK)
+		return ERROR;
+	if(sort_comments()!=OK)
+		return ERROR;
+
 	return OK;
         }
 
