C语言简单数据缓存实现
2008-12-03 13:04
393 查看
/**
example: How to easily Cache in C.
Author: suxiaojack
Date:2008.12
Licence:No Limited.
看看Lua源代码的test中一段代码:
fib.lua
-----------
-- fibonacci function with cache
-- very inefficient fibonacci function
function fib(n)
N=N+1
if n<2 then
return n
else
return fib(n-1)+fib(n-2)
end
end
-- a general-purpose value cache
function cache(f)
local c={}
return function (x)
local y=c[x]
if not y then
y=f(x)
c[x]=y
end
return y
end
end
-- run and time it
function test(s,f)
N=0
local c=os.clock()
local v=f(n)
local t=os.clock()-c
print(s,n,v,t,N)
end
n=arg[1] or 24 -- for other values, do lua fib.lua XX
n=tonumber(n)
print("","n","value","time","evals")
test("plain",fib)
fib=cache(fib)
test("cached",fib)
-----------
**********************************
实在是太漂亮了!不修改原函数的情况下,动态修改替换,完成了缓存数据的工作。
javascript等其他有些动态语言也可以做到,这种解析。
其调用过程实质如何?
原本有个fib
后来返回一个修改过的匿名函数给fib,假如名为fib_patch
调用fib实际调用的是
(see fib) | (hide fib)
fib_patch<<--->>fib
有交叉的!!
***********************************
利用C可以直接实现返回一个函数吗?
返回一个函数指针是可以的。但是无法简单做到修改原函数过程来回调新函数。
除非使用汇编硬编码,太麻烦了还不通用!!
为什么要用cache?无非是为查表提高递归效率。
为什么要保持原函数?无非是想使用原函数设计时的算法,而不重新写自带Cache的算法。
只有退而求其次,在少量修改原函数,保持算法形式不变的情况下,实现Cache添加。
看看正文:
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//NIL must be nicety
#define NIL (-1)
#define CACHESIZE 1024
#define CacheProc(name) name_patch
#define Cache(name) name_cache
#define InitCacheFor(name) memset(name_cache,NIL,CACHESIZE*sizeof(int))
#define GEN_CACHE_PROC(name)/
int Cache(name)[CACHESIZE];/
int CacheProc(name)(int n)/
{/
if(Cache(name)
==NIL)/
{/
Cache(name)
=name(n);/
};/
return Cache(name)
;/
}
int fib(int);
int fib2(int);
int CacheProc(fib2)(int);
int fib(int n)
{
if (n<=2)return 1;
else
return fib(n-2)+fib(n-1);
}
/**
to keep form as fib
just need to call CacheProc
保持算法形式上和fib一样
**/
int fib2(int n)
{
printf("fib2 be called:%d/n",n);
if (n<=2)return 1;
else
return CacheProc(fib2)(n-2)+CacheProc(fib2)(n-1);
}
/** to creat
int Cache(fib2)[CACHESIZE];
int CacheProc(fib2)(int n)
{
if(Cache(fib2)
==NIL)
{
Cache(fib2)
=fib2(n);
};
return Cache(fib2)
;
}
use GEN_CACHE_PROC**/
GEN_CACHE_PROC(fib2);
//
int main()
{
InitCacheFor(fib2);
while(1)
{
int N;
printf("intput N (<=0 exit):");
if(scanf("%d",&N)==1)
{
if(N>=1)
{
printf("fib(%d)=%d/n",N,fib(N));
printf("cached fib2(%d)=%d/n",N,fib2(N));
}else
{
exit(0);
};
}else
{
char bad[1024];
scanf("%s",bad);
}
};
return 0;
}
/**
由上面可见,如果C的预处理提供给用户获取旧源码的接口,抒写C会更方便。
比如能获取fib函数的内容。让用户再次修改内容重定义。
当然,这个预处理工具C没有提供,但是自己添加一个动态patch文件工具
是比较容易的。(对原代码文件做修改,并生成新文件的工具)
**/
example: How to easily Cache in C.
Author: suxiaojack
Date:2008.12
Licence:No Limited.
看看Lua源代码的test中一段代码:
fib.lua
-----------
-- fibonacci function with cache
-- very inefficient fibonacci function
function fib(n)
N=N+1
if n<2 then
return n
else
return fib(n-1)+fib(n-2)
end
end
-- a general-purpose value cache
function cache(f)
local c={}
return function (x)
local y=c[x]
if not y then
y=f(x)
c[x]=y
end
return y
end
end
-- run and time it
function test(s,f)
N=0
local c=os.clock()
local v=f(n)
local t=os.clock()-c
print(s,n,v,t,N)
end
n=arg[1] or 24 -- for other values, do lua fib.lua XX
n=tonumber(n)
print("","n","value","time","evals")
test("plain",fib)
fib=cache(fib)
test("cached",fib)
-----------
**********************************
实在是太漂亮了!不修改原函数的情况下,动态修改替换,完成了缓存数据的工作。
javascript等其他有些动态语言也可以做到,这种解析。
其调用过程实质如何?
原本有个fib
后来返回一个修改过的匿名函数给fib,假如名为fib_patch
调用fib实际调用的是
(see fib) | (hide fib)
fib_patch<<--->>fib
有交叉的!!
***********************************
利用C可以直接实现返回一个函数吗?
返回一个函数指针是可以的。但是无法简单做到修改原函数过程来回调新函数。
除非使用汇编硬编码,太麻烦了还不通用!!
为什么要用cache?无非是为查表提高递归效率。
为什么要保持原函数?无非是想使用原函数设计时的算法,而不重新写自带Cache的算法。
只有退而求其次,在少量修改原函数,保持算法形式不变的情况下,实现Cache添加。
看看正文:
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//NIL must be nicety
#define NIL (-1)
#define CACHESIZE 1024
#define CacheProc(name) name_patch
#define Cache(name) name_cache
#define InitCacheFor(name) memset(name_cache,NIL,CACHESIZE*sizeof(int))
#define GEN_CACHE_PROC(name)/
int Cache(name)[CACHESIZE];/
int CacheProc(name)(int n)/
{/
if(Cache(name)
==NIL)/
{/
Cache(name)
=name(n);/
};/
return Cache(name)
;/
}
int fib(int);
int fib2(int);
int CacheProc(fib2)(int);
int fib(int n)
{
if (n<=2)return 1;
else
return fib(n-2)+fib(n-1);
}
/**
to keep form as fib
just need to call CacheProc
保持算法形式上和fib一样
**/
int fib2(int n)
{
printf("fib2 be called:%d/n",n);
if (n<=2)return 1;
else
return CacheProc(fib2)(n-2)+CacheProc(fib2)(n-1);
}
/** to creat
int Cache(fib2)[CACHESIZE];
int CacheProc(fib2)(int n)
{
if(Cache(fib2)
==NIL)
{
Cache(fib2)
=fib2(n);
};
return Cache(fib2)
;
}
use GEN_CACHE_PROC**/
GEN_CACHE_PROC(fib2);
//
int main()
{
InitCacheFor(fib2);
while(1)
{
int N;
printf("intput N (<=0 exit):");
if(scanf("%d",&N)==1)
{
if(N>=1)
{
printf("fib(%d)=%d/n",N,fib(N));
printf("cached fib2(%d)=%d/n",N,fib2(N));
}else
{
exit(0);
};
}else
{
char bad[1024];
scanf("%s",bad);
}
};
return 0;
}
/**
由上面可见,如果C的预处理提供给用户获取旧源码的接口,抒写C会更方便。
比如能获取fib函数的内容。让用户再次修改内容重定义。
当然,这个预处理工具C没有提供,但是自己添加一个动态patch文件工具
是比较容易的。(对原代码文件做修改,并生成新文件的工具)
**/
相关文章推荐
- [数据结构]顺序表的C语言简单实现
- jQuery数据缓存功能的实现思路及简单模拟
- jQuery数据缓存功能的解析及简单实现
- [数据结构]单链表C语言的简单实现
- [数据结构]图邻接矩阵C语言简单实现
- [数据结构]图的DFS用栈消除递归的C语言简单实现
- 一个简单的JavaScript数据缓存系统实现代码
- 【C语言 数据结构】 简单线性表实现
- 一个简单的JavaScript数据缓存系统实现代码
- jQuery数据缓存功能的实现思路及简单模拟
- Linux下C语言实现的简单使用线程向FIFO里写入与读取数据的例子
- [数据结构]图基于邻接矩阵的BFS与DFS的C语言简单实现
- Android简单实现 缓存数据
- jQuery数据缓存功能的解析及简单实现
- 数据结构 学习笔记之:静态链表--史上最简单的C语言实现——只为掌握概念——不清楚静态链表的鸟鸟们有福了!
- 字符串拷贝的简单C语言实现
- 【转】使用storyboard实现页面跳转,简单的数据传递
- 在asp.net 中实现维护数据缓存
- 数据结构——队列(C语言实现)
- 简单层次状态机的C语言实现