#
# Copyright 2016-2018, Intel Corporation
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# TEST_SPARSE.ps1 -- compare performance of various methods of creating
# sparse files on Windows
#
# usage: .\TEST_SPARSE.ps1 filename length repeats
#
if ($args.count -lt 3) {
Write-Error "usage: sparse.ps1 filename length repeats"
exit 1
}
$path = $args[0]
$size = $args[1]
$count = $args[2]
#
# epoch -- get timestamp
#
function epoch {
return [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalMilliseconds
}
#
# remove_file -- remove file if exists
#
function remove_file {
if (test-path $args[0]) {
rm -force $args[0]
}
}
#
# create_holey_file1 -- create sparse file using 'sparsefile' utility
#
function create_holey_file1 {
$fname = $args[0]
$size = $args[1]
& '..\..\..\x64\debug\sparsefile.exe' $fname $size
if ($LASTEXITCODE -ne 0) {
Write-Error "Error $LASTEXITCODE with sparsefile create"
exit $LASTEXITCODE
}
Write-Host -NoNewline "."
}
#
# create_holey_file2 -- create sparse file using 'powershell' & 'fsutil'
#
function create_holey_file2 {
$fname = $args[0]
$size = $args[1]
$f = [System.IO.File]::Create($fname)
$f.Close()
# XXX: How to mark file as sparse using pure PowerShell API?
# Setting 'SparseFile' attribute in PS does not work for some reason.
# mark file as sparse
& fsutil sparse setflag $path
$f = [System.IO.File]::Open($fname, "Append")
$f.SetLength($size)
$f.Close()
Write-Host -NoNewline "."
}
#
# create_holey_file3 -- create sparse file using 'fsutil'
#
function create_holey_file3 {
$fname = $args[0]
$size = $args[1]
& "FSUtil" File CreateNew $fname $size
if ($LASTEXITCODE -ne 0) {
Write-Error "Error $LASTEXITCODE with FSUTIL create"
exit $LASTEXITCODE
}
& "FSUtil" Sparse SetFlag $fname
if ($LASTEXITCODE -ne 0) {
Write-Error "Error $LASTEXITCODE with FSUTIL setFlag"
exit $LASTEXITCODE
}
& "FSUtil" Sparse SetRange $fname 0 $size
if ($LASTEXITCODE -ne 0) {
Write-Error "Error $LASTEXITCODE with FSUTIL setRange"
exit $LASTEXITCODE
}
Write-Host -NoNewline "."
}
$start = epoch
for ($i=1;$i -lt $count;$i++) {
remove_file $path
create_holey_file1 $path $size
}
$end = epoch
$t = ($end - $start) / 1000
Write-Host "`nsparsefile: $t seconds"
$start = epoch
for ($i=1;$i -lt $count;$i++) {
remove_file $path
create_holey_file2 $path $size
}
$end = epoch
$t = ($end - $start) / 1000
Write-Host "`npowershell + fsutil: $t seconds"
$start = epoch
for ($i=1;$i -lt $count;$i++) {
remove_file $path
create_holey_file3 $path $size
}
$end = epoch
$t = ($end - $start) / 1000
Write-Host "`nfsutil: $t seconds"