The slow work with memory in Haiku

2021-09-30

Progress in Haiku OS

In stable is extremny slow, but in developing version is all normal.

The error is minimal fixed in version hrev55464 and later.

Haiku shredder 1 hrev55464 Sep 30 2021 06:38:30 x86_64 x86_64 Haiku

2021-09-18

Progress in Haiku OS

The change in develop upstream:
(16:52:37) nekobot: [haiku/haiku] waddlesplash pushed 1 commit to master [hrev55422] - https://git.haiku-os.org/haiku/log/?qt=range&q=abe937985dda+%5E64e742def3db
(16:52:37) nekobot: [haiku/haiku] abe937985dda - libroot: Replace glibc search implementation with musl's.

Result

This tests are only in Haiku.

System with update of packages and added packages
Complet time [s]CSV file
to memory [s]
memory data
to hash table [s]
Export
to file [s]
CountType
0.3963290.0228610.0000050.0001291gcc
0.3539200.0229270.0000050.0001231clang
0.3865680.0228650.0002930.0000931gcc + glib
0.3961330.0228520.0003170.0001101clang + glib
0.5421750.1598090.0000070.00012110gcc
0.5098650.1599200.0000070.00013110clang
0.4914770.1597980.0003210.00009910gcc + glib
0.4964420.1599210.0003230.00010110clang + glib
1.8684201.5305750.0000750.000129100gcc
1.8697771.5295850.0000680.000124100clang
1.8771061.5294200.0002150.000159100gcc + glib
1.8691881.5319100.0002390.000112100clang + glib
15.55704815.2258340.0002820.0001861000gcc
15.57412415.2305010.0002760.0002061000clang
15.58236415.2206140.0004060.0002601000gcc + glib
15.59808615.2472260.0003920.0002611000clang + glib
152.018423151.6609180.0024990.00077010000gcc
152.079786151.6994670.0022760.00078310000clang
151.854705151.5295160.0029560.00148410000gcc + glib
151.942997151.6140040.0030140.00146510000clang + glib

Source:

Hardwer/OS

It's as in a test on 2021-08-28.

System version

Haiku shredder 1 hrev55436 Sep 18 2021 07:09:53 x86_64 x86_64 Haiku
2021-08-28

Task

Export key + value from input CSV string and store in memory.

Resolution

If I store all key+value items into memory, the process is very slow. Whether it is stored as a array or a linked list.

Statistic for array

Metal n. 1 Metal n. 2
HaikuLinuxHaiku
CountTime [s]Time [s]SlowerTime [s]
100.1621310.00238268 x0.087729
1001.5474690.002695574 x0.837152
100015.4333410.0029325264 x8.562566
10000154.9902840.00729621243 x82.722402
1000001470.9879450.05074528988 x786.982834
Systems:
HaikuHaiku, Revision 1, Beta 3, ISO: haiku-r1beta3-x86_64-anyboot.iso
LinuxDebian (testing), last update 2021-08-15.

Test is on real metal, none virtualization. The source code is here.

Tests found a error(s)

Metal n. 1 Metal n. 2
Haiku Linux Haiku
TestTime [µs]Time [µs]% of Linux valueTime [µs]
test_random (1M items)21 69926 69181 %15 466
test_alloc_memory (1M items)186 947110 507169 %138 369
test_alloc_memory_and_set (1M items)221 716126 606175 %150 741
test_set_100MB_memory_1B659 278573 324115 %416 741
test_set_100MB_memory_10B14 77218 45580 %9 672
test_set_100MB_memory_100B37 52582 34146 %57 823
test_set_100MB_memory_1000B14 25057 44725 %14 733
Systems:
HaikuHaiku, Revision 1, Beta 3, ISO: haiku-r1beta3-x86_64-anyboot.iso
LinuxDebian (testing), last update 2021-08-15.

Test is on real metal, none virtualization.

Source code

Run test

gcc memory_test.c -o memory_test -O0 -fPIC -flto -std=c99 -march=x86-64
./memory_test

Program

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <search.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>

#ifndef COUNT
 #define COUNT 1000000 // 1M
#endif

double micro_time()
{
	struct timeval actual;
	char buffer[20];
	char *pointer;
	double actual_micro_time;
	
	gettimeofday(&actual, NULL);
	snprintf(buffer, 20, "%ld.%06ld", actual.tv_sec,actual.tv_usec);
	pointer=strchr(buffer, '.');
	*(pointer+7)='\0';
		
	sscanf(buffer, "%lf", &actual_micro_time);
	
	return actual_micro_time;
}

double test_random()
{
	int a;
	int number;
	double time_start;
	double time_end;
	
	srand(time(NULL));
	
	time_start=micro_time();
	for(a=0;a<COUNT; a++)
		number=rand();
	time_end=micro_time();
	
	return time_end-time_start;
}

double test_alloc_memory()
{
	int a;
	char *block;
	double time_start;
	double time_end;
	
	time_start=micro_time();
	for(a=0;a<COUNT; a++)
	{
		block=(char *) malloc(5);
		if(block == NULL)
		{
			perror("test alloc memory");
			exit(1);
		}
		
		// free(block);
	}
	time_end=micro_time();
	
	return time_end-time_start;
}

double test_alloc_memory_and_set()
{
	int a;
	char *block;
	double time_start;
	double time_end;
	const char *block_default="1234567890";
	
	srand(time(NULL));
	
	time_start=micro_time();
	for(a=0;a<COUNT; a++)
	{
		block=(char *) malloc(11);
		if(block == NULL)
		{
			perror("test alloc memory");
			exit(1);
		}
		
		strcpy(block, block_default);
		
		// free(block);
	}
	time_end=micro_time();
	
	return time_end-time_start;
}

double test_set_100MB_memory_1B()
{
	int a;
	double time_start;
	double time_end;
	
	char *memory_block;
	char *write;
	
	memory_block=(char *) malloc(100000000);
	if(memory_block == NULL)
	{
		perror("test_set_100MB_memory_1B");
		exit(2);
	}
	
	time_start=micro_time();
	for(a=0,write=memory_block;a<100000000; a++,write++)
	{
		*write='!';
	}
	time_end=micro_time();
	
	free(memory_block);
	
	return time_end-time_start;
}

double test_set_100MB_memory_10B()
{
	int a;
	double time_start;
	double time_end;
	
	char *memory_block;
	char *write;
	
	memory_block=(char *) malloc(100000000);
	if(memory_block == NULL)
	{
		perror("test_set_100MB_memory_1B");
		exit(2);
	}
	
	time_start=micro_time();
	for(a=0,write=memory_block;a<1000000; a++,write+=10)
		memcpy(write, "!!!!!!!!!!", 10);
	time_end=micro_time();
	
	free(memory_block);
	
	return time_end-time_start;
}

double test_set_100MB_memory_100B()
{
	int a;
	double time_start;
	double time_end;
	
	char *memory_block;
	char *write;
	
	memory_block=(char *) malloc(100000000);
	if(memory_block == NULL)
	{
		perror("test_set_100MB_memory_1B");
		exit(2);
	}
	
	time_start=micro_time();
	for(a=0,write=memory_block;a<1000000; a++,write+=100)
		memcpy(write, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 100);
	time_end=micro_time();
	
	free(memory_block);
	
	return time_end-time_start;
}
double test_set_100MB_memory_1000B()
{
	int a;
	double time_start;
	double time_end;
	
	char *memory_block;
	char *write;
	
	memory_block=(char *) malloc(100000000);
	if(memory_block == NULL)
	{
		perror("test_set_100MB_memory_1B");
		exit(2);
	}
	
	time_start=micro_time();
	for(a=0,write=memory_block;a<100000; a++,write+=1000)
		memcpy(write, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 100);
	time_end=micro_time();
	
	free(memory_block);
	
	return time_end-time_start;
}

int main()
{
	printf("%f s - test_random\n", test_random());
	printf("%f s - test_alloc_memory\n", test_alloc_memory());
	printf("%f s - test_alloc_memory_and_set\n", test_alloc_memory_and_set());
	printf("%f s - test_set_100MB_memory_1B\n", test_set_100MB_memory_1B());
	printf("%f s - test_set_100MB_memory_10B\n", test_set_100MB_memory_10B());
	printf("%f s - test_set_100MB_memory_100B\n", test_set_100MB_memory_100B());
	printf("%f s - test_set_100MB_memory_1000B\n", test_set_100MB_memory_1000B());
	return 0;
}

Last change: 2021-09-18 UTC.
Author: Dušan Kreheľ