Sed:降低数据处理速度

时间:2017-11-01 13:32:30

标签: sed gnuplot

在使用Gnuplot绘制数据之前,我有大型文件(10-20 GB),我使用Sed进行预处理。这些图保存为.png图像。 data文件包含images个大小为matrix_size x matrix_size的矩阵。大小为data的两个(images=3)矩阵的matrix_size=2文件如下所示:

 1 2
 3 2
 1 5
 3 4
 5 2
 2 3

我使用Sed来提取data文件的每个矩阵。在开始时,这发生得非常快,我的脚本每秒产生一个图像。但过了一会儿,每张图片的时间增加到25秒。为什么会这样?这是我的代码:

unset border
unset key
unset xtics
unset ytics
unset ztics
unset colorbox

set autoscale fix
set size ratio -1

file = 'data'
matrix_size = 1000
images = 1000

sizeX = matrix_size
sizeY = matrix_size
set xrange [1:matrix_size]
set yrange [1:matrix_size]
set terminal png size sizeX, sizeY

getMatrix(fileName, n, i) = sprintf("<sed -n '%d,%dp;%dq' '%s'", (i-1)*n + 1, i*n, i*n+1, fileName)

do for [i=1:images]{
    t0 = strftime('%s', time(0))    
    set output sprintf('%05d_%s.png', i, file)
    plot getMatrix(file, matrix_size, i) matrix with image
    t1 = strftime('%s', time(0))
    print(sprintf('%d %d', t1-t0, i))
}

以下是每张图片绘制时间的秒数。一开始非常快,然后又慢又慢:

enter image description here

2 个答案:

答案 0 :(得分:2)

我建议您使用split预先将所有矩阵提取到单个文件中,一次性传递:

split -a 4 -d -l matrix_size data matrix-

如果我理解您的文件格式,那么会将每个矩阵放在一个名为matrix-0000matrix-0001的单独文件中。

答案 1 :(得分:1)

如评论中所述,sed命令始终必须从数据文件的开头开始搜索第i帧,这可能需要很长时间。我不知道在gnuplot中使用循环结构时是否可以避免这种情况。但是,您可以使用awk(也可能是sed)一次性浏览数据文件,并插入gnuplot命令以设置并完成右侧的帧数字。我很好奇这样的事情对你有用吗?如果它这样做我认为它不会显示在后期帧的减速:

unset border
unset key
unset xtics
unset ytics
unset ztics
unset colorbox

set autoscale fix
set size ratio -1

matrix_size = 1000

sizeX = matrix_size
sizeY = matrix_size
set xrange [-0.5:matrix_size-0.5]
set yrange [-0.5:matrix_size-0.5]
set terminal png size sizeX, sizeY

file = "data"
load sprintf("< cat %s | awk \'\
    BEGIN {i = 0;} \
    NR %% %d == 1 \{ \
      print \"print \\\"Creating image \" i \" \\\"\"; \
      print \"set output \\\"%s_\" i \".png\\\"\"; \
      print \"plot \\\"-\\\" matrix with image\"; \
    } \
    {print;} \
    NR %% %d == 0 { \
      print \"e\\ne\"; \
      i = i+1; \
    } \
  \'", file, matrix_size, file, matrix_size)

说明

根据要求,以下是此代码的简要说明。举个例子,我们假设文件data包含2个矩阵,每个矩阵大小为3x3:

1 2 3
4 5 6
7 8 9
10 11 12
16 17 18
13 14 15

命令

cat data | awk 'NR % 3 == 1 {print "plot \"-\" matrix with image";} {print;} NR % 3 == 0 {print "e\ne";}'

阅读此文件并创建以下输出:

plot "-" matrix with image
1 2 3
4 5 6
7 8 9
e
e
plot "-" matrix with image
10 11 12
16 17 18
13 14 15
e
e

这是有效的gnuplot代码。它是通过在第1行和第4行之前插入行plot "-" matrix with image,在第3行和第6行之后插入两个e来实现的。您可以将此输出保存到文件中并让gnuplot运行它,或者您可以运行它直接来自gnuplot内部的代码使用load sprintf("< cat data | awk ....构造。这很好,因为你只有一个脚本,但你必须小心逃避引号和反斜杠字符。上面的代码还添加了一个计数器,以便为每个图像使用新的文件名(以及每个图像的set output data_FRAMENUMBER.png行)。

获取大data文件并将其拆分为许多较小的文件可能更容易,每个框架一个。但是,如果由于某种原因你不能这样做(在目录中有数千个文件可能会很烦人),或者你必须保留一个大文件以进行其他类型的处理,那么这是一个合理的解决方案。