Improve Powershell Performance to Generate a Random File

后端 未结 4 1196
花落未央
花落未央 2020-12-10 23:09

I\'d like to user Powershell to create a random text file for use in basic system testing (upload, download, checksum, etc). I\'ve used the following articles and co

4条回答
  •  清歌不尽
    2020-12-10 23:47

    If you are ok with punctuation you can use this:

    Add-Type -AssemblyName System.Web
    #get a random filename in the present working directory
    $fn = [System.IO.Path]::Combine($pwd, [GUID]::NewGuid().ToString("N") + '.txt')
    #set number of iterations
    $count = 1mb/128
    do{
      #Write the 1267 chars plus eol
      [System.Web.Security.Membership]::GeneratePassword(126,0) | Out-File $fn -Append ascii
      #decrement the counter
      $count--
    }while($count -gt 0)
    

    Which gets you to around 7 seconds. Sample Output:

    0b5rc@EXV|e{kftc+1+Xn$-c%-*9q_9L}p=I=k@zrDg@HaJDcl}B(38i&m{lV@vlq%5h/a?m2X!yo]qs0=pEw:Tn4wb5F$k$O85$8F.QLvUzA{@X2-w%5(3k;BE2Qi
    

    Using a stream writer instead of Out-File -Append avoids the open/close cycles and drops the same to 62 milliseconds.

    Add-Type -AssemblyName System.Web
    #get a random filename in the present working directory
    $fn = [System.IO.Path]::Combine($pwd, [GUID]::NewGuid().ToString("N") + '.txt')
    #set number of iterations
    $count = 1mb/128
    #create a filestream
    $fs = New-Object System.IO.FileStream($fn,[System.IO.FileMode]::CreateNew)
    #create a streamwriter
    $sw = New-Object System.IO.StreamWriter($fs,[System.Text.Encoding]::ASCII,128)
    do{
         #Write the 1267 chars plus eol
         $sw.WriteLine([System.Web.Security.Membership]::GeneratePassword(126,0))
         #decrement the counter
         $count--
    }while($count -gt 0)
    #close the streamwriter
    $sw.Close()
    #close the filestream
    $fs.Close()
    

    You could also use a stringbuilder, and GUIDs to generate pseudorandom numbers and lowercase.

    #get a random filename in the present working directory
    $fn = [System.IO.Path]::Combine($pwd, [GUID]::NewGuid().ToString("N") + '.txt')
    #set number of iterations
    $count = 1mb/128
    #create a filestream
    $fs = New-Object System.IO.FileStream($fn,[System.IO.FileMode]::CreateNew)
    #create a streamwriter
    $sw = New-Object System.IO.StreamWriter($fs,[System.Text.Encoding]::ASCII,128)
    do{
        $sb = New-Object System.Text.StringBuilder 126,126
        0..3 | %{$sb.Append([GUID]::NewGuid().ToString("N"))} 2> $null
        $sw.WriteLine($sb.ToString())
        #decrement the counter
        $count--
    }while($count -gt 0)
    #close the streamwriter
    $sw.Close()
    #close the filestream
    $fs.Close()
    

    This takes about 4 seconds and generates the following sample:

    1fef6ccabc624e4dbe13a0415764fd2c58aa873377c7465eaecabdf6ba6fdf71c55496600a374c4c8cff75be46b1fe474230231ffccc4e3aa2753391afb32c
    

    If you are hell bent to use the same chars as in your sample you can do so with the following:

    #get a random filename in the present working directory
    $fn = [System.IO.Path]::Combine($pwd, [GUID]::NewGuid().ToString("N") + '.txt')
    #array of valid chars
    $chars = [char[]] ([char]'0'..[char]'9' + [char]'A'..[char]'Z' + [char]'a'..[char]'z')
    #create a random object
    $rand = New-Object System.Random
    #set number of iterations
    $count = 1mb/128
    #get length of valid character array
    $charslength = $chars.length
    #create a filestream
    $fs = New-Object System.IO.FileStream($fn,[System.IO.FileMode]::CreateNew)
    #create a streamwriter
    $sw = New-Object System.IO.StreamWriter($fs,[System.Text.Encoding]::ASCII,128)
    do{
        #get 126 random chars This is the major slowdown
        $randchars = 1..126 | %{$chars[$rand.Next(0,$charslength)]}
        #Write the 1267 chars plus eol
        $sw.WriteLine([System.Text.Encoding]::ASCII.GetString($randchars))
        #decrement the counter
        $count--
    }while($count -gt 0)
    #close the streamwriter
    $sw.Close()
    #close the filestream
    $fs.Close()
    

    This takes ~27 seconds and generates the following sample:

    Fev31lweOXaYKELzWOo1YJn8LpZoxonWjxQYhgZbR62EmgjHit5J1LrvqniBB7hZj4pNonIpoCZSHYLf5H63iUUN6UhtyOQKPSViqMTvbGUomPeIR36t1drEZSHJ6O
    

    Indexing the char array and the out-file -Append opening and closing the file each time is a major slowdown.

提交回复
热议问题