Hi:
    I am involved in the optimization of the performance of a  memcached
client library now(written by c).
    And I found that if I want to set a big value(say: 9000 bytes long),
prepare all the data and call write once or split the data to two writes
will cause dramatic performance difference: the latter is about 100 times
slow than the former.
    I do the experiment on my own machine, a single core T43 notebook. Run
one memcached server instance with the command "/usr/bin/memcached -m 64 -p
11211 -u root", and write code to connect to the 11211 port to write the set
operation data. Iterate 100 times to set a 9000 bytes value each time. The
client.c code prepares all the data and write the data once. The
client_multi_write.c code splite the data to two writes. Run the two
programs to get the above result.
   I think it's partly related to the implement of the memcached? Anybody to
confirm the above experiment or give me an explanation?
   Thanks.


-- 
Chen Yin
School of EE & CS, Peking University
/* client.c */

#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>

char buffer[9024];

int c_set(char *buffer, char* key, size_t key_len, size_t value_len, uint32_t flags, unsigned long long expiration)
{
	int write_len;
	write_len = snprintf(buffer, 1024, "%s %.*s %u %llu %zu\r\n", "set",
			(int)key_len, key, flags,
			(unsigned long long)expiration, value_len);

	return write_len;
}

main(int argc,char *argv[])
{
	int create_socket;
	struct sockaddr_in address;
	char *host = "127.0.0.1";

	if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)
		printf("The Socket was created\n");

	address.sin_family = AF_INET;
	address.sin_port = htons(11211);
	inet_pton(AF_INET,host,&address.sin_addr);

	if (connect(create_socket, (struct sockaddr *)&address, sizeof(address)) == 0)
		printf("The connection was accepted with the server %s...\n",inet_ntoa(address.sin_addr));

	int i;
	int write_len;
	int ret;
	char response[100];

	for(i = 1; i <= 100; ++i) {

		// set the key "fortest" to a value whose length is 9000
		write_len = c_set(buffer, "fortest", 8, 9000, 0, 0);
		printf("write_len is %d\n", write_len);

		buffer[9022] = '\r';
		buffer[9023] = '\n';
		ret = write(create_socket, buffer, 9024);

		printf("begin reading\n");
		ret = read(create_socket, response, 100);
		if(ret > 0) {
			printf("read data(%.*s)\n", ret, response);
		} else {
			perror("read error:");
		}
	}
out:
	close(create_socket);
}
/* client.c */

#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>

#define BUFFER_SIZE 8196
char buffer[BUFFER_SIZE];

int c_set(char *buffer, char* key, size_t key_len, size_t value_len, uint32_t flags, unsigned long long expiration)
{
	int write_len;
	write_len = snprintf(buffer, 1024, "%s %.*s %u %llu %zu\r\n", "set",
			(int)key_len, key, flags,
			(unsigned long long)expiration, value_len);

	return write_len;
}

main(int argc,char *argv[])
{
	int create_socket;
	struct sockaddr_in address;
	char *host = "127.0.0.1";

	if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)
		printf("The Socket was created\n");

	address.sin_family = AF_INET;
	address.sin_port = htons(11211);
	inet_pton(AF_INET,host,&address.sin_addr);

	if (connect(create_socket, (struct sockaddr *)&address, sizeof(address)) == 0)
		printf("The connection was accepted with the server %s...\n",inet_ntoa(address.sin_addr));

	int i;
	int write_len;
	int ret;
	char response[100];

	for(i = 1; i <= 100; ++i) {
		// set the key "fortest" to a value whose length is 9000

		write_len = c_set(buffer, "fortest", 8, 9000, 0, 0);
		printf("write_len is %d\n", write_len);

		ret = write(create_socket, buffer, BUFFER_SIZE);
		int left_len = 9000 - BUFFER_SIZE + write_len;

		buffer[left_len] = '\r';
		buffer[left_len + 1] = '\n';
		ret = write(create_socket, buffer, left_len + 2);

		printf("begin reading\n");
		ret = read(create_socket, response, 100);
		if(ret > 0) {
			printf("read data(%.*s)\n", ret, response);
		} else {
			perror("read error:");
		}
	}
out:
	close(create_socket);
}

Reply via email to