簡體   English   中英

shell腳本內存不足

[英]shell script runs out of memory

我編寫了以下隨機數生成器shell腳本:

for i in $(seq 1 $1) #for as many times, as the first argument ($1) defines...
do 
echo "$i $((RANDOM%$2))" #print the current iteration number and a random number in [0, $2)
done

我這樣運行:

./generator.sh 1000000000 101 > data.txt

在[0,100]中生成1行id和隨機數的1B行,並將該數據存儲在文件data.txt

我想要的輸出是:

1 39
2 95
3 61
4 27
5 85
6 44
7 49
8 75
9 52
10 66
...

它適用於少量行,但對於1B,我得到以下OOM錯誤:

./generator.sh:xrealloc:../bash/subst.c:5179:無法分配18446744071562067968字節(分配4299137024字節)

我程序的哪一部分會產生錯誤? 我怎么能逐行編寫data.txt文件? 我嘗試用以下方法替換echo線:

echo "$i $((RANDOM%$2))" >> $3

其中3美元是data.txt ,但我認為沒有區別。

問題是你的for循環:

for i in $(seq 1 $1) 

這將首先展開$(seq 1 $1)創造一個非常大名單,然后您可以傳遞給for

但是,使用while ,我們可以逐行讀取seq的輸出,這將占用少量內存:

seq 1 1000000000 | while read i; do
        echo $i
done

$(seq 1 $1)在迭代之前計算整個列表。 因此需要內存來存儲10^9數字的整個列表,這很多。

我不確定你是否可以seq運行seq ,即只在需要時獲取下一個號碼。 你可以做一個簡單的for循環:

for ((i=0; i<$1;++i))
do
  echo "$i $((RANDOM%$2))"
done

如果你想要它快,這應該工作。

您需要使用表單使用g ++編譯它

g++ -o <executable> <C++file>

例如我這樣做了

g++ -o inseq.exe CTest.cpp

CTest.cpp

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <sstream>

int main (int argc,char *argv[])
{
    std::stringstream ss;
    int x = atoi(argv[1]);
        for(int i=1;i<=x;i++)
        {
                ss << i << "\n";
                if(i%10000==0)
                {
                        std::cout << ss.rdbuf();
                        ss.clear();
                        ss.str(std::string());

                }
        }
std::cout << ss.rdbuf();
ss.clear();
ss.str(std::string());
}

速度比較

對於1000000行文件,每種方法的最低速度為3次測試。

Jidder

$ time ./inseq 1000000 > file

real    0m0.143s
user    0m0.131s
sys     0m0.011s

Carpetsmoker

$ cat Carpet.sh

#!/bin/bash

seq 1 $1 | while read i; do
    echo $i
done

$ time ./Carpet.sh 1000000 > file

 real    0m12.223s
 user    0m9.753s
 sys     0m2.140s

Hari Shankar

$ cat Hari.sh

#!/bin/bash

for ((i=0; i<$1;++i))
do
  echo "$i $((RANDOM%$2))"
done

$ time ./Hari.sh 1000000 > file
real    0m9.729s
user    0m8.084s
sys     0m1.064s

從結果中可以看出,我的方式稍微快了大約60-70 *。

編輯

因為python很棒

$ cat Py.sh

#!/usr/bin/python

for x in xrange(1, 1000000):
print (x)

$ time ./Py.sh >file

real    0m0.543s
user    0m0.499s
sys     0m0.016s

4 *比c ++慢,所以如果文件需要一個小時才能使這兩行有4個。

編輯2

決定在1000000000行文件上嘗試Python和c ++

對於沒有CPU密集型的任務,這似乎是使用lottt的cpu

PID USER  %CPU   TIME+  COMMAND
56056 me  96     2:51.43 Py.sh

Python的結果

real    9m37.133s
user    8m53.550s
sys     0m8.348s

c ++的結果

 real    3m9.047s
 user    2m53.400s
 sys     0m2.842s

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM