2017-03-07 48 views
2

我正在处理的应用程序需要使计数器的值在多个调用中保持不变,以便每当应用程序再次启动时,计数器的值被读回并从那里继续计数。值应该以人类可读的形式存储,以便它可以很容易地检查,如果出现这种需要,应该自动更新,以便故障不会混淆以前的持续值。使用符号链接来存储数据

使用普通的旧文本文件看起来太无聊了,所以经过一些创造性思维后,我发现我可以通过将计数器存储为符号链接目标来实现相同的目标。

基本上,用sh作为原型语言,而不是做

echo $counter > file.tmp && mv file.tmp file || rm -f file.tmp 

我会做

ln -s $counter file.tmp && mv file.tmp file || rm -f file.tmp 

后一种方法的优点是,我只需要一个系统调用写入档案,而不是在前一种情况下的至少 3。

作为额外的奖励,这样做从外壳的ls -l自动地显示文件的内容:

$ ls -l the.counter.is 
lrwxrwxrwx 1 fabio fabio 4 mar 7 01:08 the.counter.is -> 1234 

至于所关注的表演,在执行上的两种方法(see it here)进行比较测试程序我PC我得到符合预期的结果,符号链接方法比标准方法快7倍左右(注意测试不关心原子性):

$ uname -a && ./linkfile 10000 4095 /tmp/test 
Linux Fabio-Asus 4.8.0-40-generiC#43-Ubuntu SMP Thu Feb 23 16:01:19 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 
Starting test... [10000, 4095] 
writeToFile: 155.537ms 
writeToLink: 23.4132ms 

然而,on coliru我得到不同的结果,略微有利于标准的做法:

uname -a && g++ -O3 -o test main.cpp && sync && ./test 10000 4095 x 
Linux stacked-crooked 4.4.0-57-generiC#78-Ubuntu SMP Fri Dec 9 23:50:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux 
Starting test... [10000, 4095] 
writeToFile: 21.8001us 
writeToLink: 33.9217us 

试验包括10000次迭代每种方法,在每次迭代写4095个字节,他们的平均执行时间。

4095字节的原因是多于那些导致symlink系统调用以ENAMETOOLONG失败的原因。

所以,问题是:

  1. 有没有人,除了疯狂的,我曾经使用过这种方法之前,存储数据?
  2. 如果是,为什么用例?
  3. 铭记我的电脑体育一个i7-6500U CPU @ 2.50GHz,你有什么想法,为什么对coliru的标准方法是如此之快比我的电脑上,无论是相对于符号链接的方式和绝对时间?如果是因为某些缓存,为什么这些缓存对我的电脑没有影响,为什么它们对符号链接方式没有积极影响?
+0

尼斯理想我会想你的性能测试结果将是极其文件系统,甚至依赖于硬件。你在本地使用什么文件系统?什么磁盘硬件? –

回答

0

我的答案:被用于存储数据

  1. 是的,我见过的符号链接。正如你已经解释的那样,在符号链接而不是文件中存储小块数据会有巨大的性能提升。我相信符号链接值直接存储在inode中,这使得存储效率更高。另一个巨大的优势是原子性 - 符号链接创建是一个原子进程,并有助于处理并发问题。
  2. 存储在符号链接的值是主要的元数据,应用特定的。例如,如果我必须构建一个分析器来逐步分析大量动态日志文件,那么我可能需要将读取的最后一个字节位置存储在符号链接中。符号链接也可以用于实现锁定。我遇到过这种情况,其中flock在NFS上不可靠,而使用符号链接。
  3. 我不知道这一点 - 有可能是一个实现差异?