linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Miao Xie <miaox@cn.fujitsu.com>
To: Chris Mason <chris.mason@oracle.com>, Yan Zheng <zheng.yan@oracle.com>
Cc: Linux Btrfs <linux-btrfs@vger.kernel.org>
Subject: Poor creat/delete files performance
Date: Wed, 18 Aug 2010 18:12:46 +0800	[thread overview]
Message-ID: <4C6BB21E.3000809@cn.fujitsu.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 779 bytes --]

Hi,

We did some performance test and found the create/delete files performance
of btrfs is very poor.

The test is that we create 50000 files and measure the file-create time
first, and then delete these 50000 files and measure the file-delete time. 
(The attached file is the reproduce program)

The result is following:
(Unit: second)
  Create file performance
		BtrFS		Ext4
  Total times:	2.462625	1.449550
  Average:	0.000049	0.000029

  Delete file performance
		BtrFS		Ext4
  Total times:	3.312796	0.997946
  Average:	0.000066	0.000020

The results were measured on a x86_64 server with 4 cores and 2 SAS disks.
By debuging, we found the btrfs spent a lot of time on searching and
inserting/removing items in the ctree.

Is anyone looking at this issue?

Regards
Miao Xie

[-- Attachment #2: creat_unlink.c --]
[-- Type: text/x-csrc, Size: 2818 bytes --]

/* gcc creat_unlink.c -o creat_unlink */
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#define UNUSED          __attribute__ ((unused))
#define PATH_SIZE       100
#define TST_DIR		"tst_dir"

int initialize(void)
{
	int ret;

	ret = mkdir(TST_DIR, 0775);
	if (ret) {
		perror("init fail - mkdir failed\n");
		goto err;
	}

	ret = chdir(TST_DIR);
	if (ret) {
		perror("init fail - chdir failed\n");
		rmdir(TST_DIR);
	}
err:
	return ret;
}

int cleanup(void)
{
	int ret;

	ret = chdir("..");
	if (ret) {
		perror("cleanup fail - chdir failed\n");
		goto err;
	}

	ret = rmdir(TST_DIR);
	if (ret)
		perror("cleanup fail - rmdir failed\n");

err:
	return ret;
}

int get_start_time(struct timeval *tv)
{
	if (gettimeofday(tv, NULL)) {
		perror("get start time failed.\n");
		return 1;
	}

	return 0;
}

void account_time(struct timeval *stv, struct timeval *etv, int files)
{
	if (gettimeofday(etv, NULL)) {
		perror("get end time failed.\n");
	} else if (files) {
		double ts;

		while (etv->tv_usec < stv->tv_usec) {
			etv->tv_sec--;
			etv->tv_usec += 1000000;
		}

		etv->tv_usec -= stv->tv_usec;
		etv->tv_sec -= stv->tv_sec;

		while (etv->tv_usec > 1000000) {
			etv->tv_usec -= 1000000;
			etv->tv_sec++;
		}

		ts = (double)etv->tv_usec / (double)1000000 + etv->tv_sec;
		printf("\tTotal files: %d\n", files);
		printf("\tTotal time: %lf\n", ts);

		ts /= files;
		printf("\tAverage time: %lf\n", ts);
	} else
		perror("Didn't create/delete any files");

}

int create_files(int nfiles)
{
	int i, fd;
	char fpath[PATH_SIZE];
	struct timeval stv, etv;

	printf("Create files:\n");
	if (get_start_time(&stv))
		return 0;

	for (i = 0; i < nfiles; i++) {
		sprintf(fpath, "%d", i);
		fd = creat(fpath, 0555);
		if (fd < 0) {
			perror("creat file failed.\n");
			break;
		}
		close(fd);
	}

	account_time(&stv, &etv, i);

	return i;
}

int unlink_files(int nfiles)
{
	int i, ret = 0;
	char fpath[PATH_SIZE];
	struct timeval stv, etv;

	printf("Delete files:\n");
	if (get_start_time(&stv))
		return 1;

	for (i = 0; i < nfiles; i++) {
		sprintf(fpath, "%d", i);
		ret = unlink(fpath);
		if (ret)
			break;
	}

	account_time(&stv, &etv, i);

	return ret;
}

int main(int argc, char **argv)
{
	int nfiles, n_done, ret;

	/* parse the options */
	if (argc != 2) {
		fprintf(stderr, "options is wrong.\n");
		fprintf(stderr, "%s [nfiles]\n", argv[0]);
		exit(1);
	}

	nfiles = atoi(argv[1]);
	if (nfiles <= 0) {
		fprintf(stderr, "option nfiles is wrong.");
		exit(1);
	}

	/* initialize - create the test directory and change the current dir */
	ret = initialize();
	if (ret)
		exit(1);

	n_done = create_files(nfiles);
	if (n_done != nfiles) {
		unlink_files(n_done);
		cleanup();
		exit(1);
	}

	ret = unlink_files(n_done);
	if (ret)
		exit(1);

	ret = cleanup();
	if (ret)
		exit(1);

	return 0;
}

             reply	other threads:[~2010-08-18 10:12 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-18 10:12 Miao Xie [this message]
2010-08-18 10:49 ` Poor creat/delete files performance Morten P.D. Stevens
2010-08-18 14:25   ` Chris Mason
2010-08-18 15:28     ` Morten P.D. Stevens
2010-08-18 15:39       ` Chris Mason
2010-08-18 16:26         ` Morten P.D. Stevens
2010-08-18 10:49 ` Leonidas Spyropoulos
2010-08-18 11:00   ` Miao Xie
2010-08-18 12:09 ` Chris Mason
2010-08-19  0:35   ` Miao Xie
2010-08-19  0:57     ` Chris Mason
2010-08-19  1:38       ` Miao Xie
2010-08-26 10:07       ` Miao Xie
2010-08-26 23:15         ` Chris Mason

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C6BB21E.3000809@cn.fujitsu.com \
    --to=miaox@cn.fujitsu.com \
    --cc=chris.mason@oracle.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=zheng.yan@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).