Skip to content

Commit 9fa1dfd

Browse files
authored
Merge pull request #12 from slimgroup/allocs
Small perf improvements
2 parents e876586 + 72091d0 commit 9fa1dfd

12 files changed

+53
-58
lines changed

Diff for: Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "SegyIO"
22
uuid = "157a0f19-4d44-4de5-a0d0-07e2f0ac4dfa"
33
authors = ["Henryk Modzelewski <[email protected]>"]
4-
version = "0.8.1"
4+
version = "0.8.2"
55

66
[deps]
77
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# SegyIO.jl
2+
23
SegyIO is a Julia package for reading and writing SEGY Rev 1 files. In addition to providing tools for reading/writing entire files, SegyIO provides a parallel scanner that reduces any number of files into a single object with direct out-of-core access to the underlying data.
34

45
[![Build Status](https://github.com/slimgroup/SegyIO.jl/workflows/CI-tests/badge.svg)](https://github.com/slimgroup/SegyIO.jl/actions?query=workflow%3ACI-tests)

Diff for: src/SegyIO.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module SegyIO
22

33
myRoot=dirname(dirname(pathof(SegyIO)))
44
CHUNKSIZE = 2048
5-
TRACE_CHUNKSIZE = 2048
5+
TRACE_CHUNKSIZE = 512
66
MB2B = 1024^2
77

88
# what's being used

Diff for: src/read/read_block.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ function read_block!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf::Int, tm
2929
tracee = min(trace + TRACE_CHUNKSIZE - 1, ntraces)
3030
chunk = length(trace:tracee)*trace_size
3131
sloc = IOBuffer(read(s, chunk))
32-
read_traces!(sloc, fh.bfh, datatype, tmp_headers, view(tmp_data, :, trace:tracee), trace, keys, th_b2s)
32+
read_traces!(sloc, view(tmp_headers, trace:tracee), view(tmp_data, :, trace:tracee), keys, th_b2s)
3333
end
3434
end

Diff for: src/read/read_block_headers.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function read_block_headers!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf:
2121
th_b2s = th_byte2sample()
2222
# Read each traceheader
2323
for trace in 1:ntraces
24-
setindex!(headers, read_traceheader(s, keys, th_b2s), trace)
24+
read_traceheader!(s, keys, th_b2s, headers[trace])
2525
skip(s, ns*4)
2626
end
2727

@@ -48,7 +48,7 @@ function read_block_headers!(b::BlockScan, ns::Int, dsf::Int, headers)
4848
th_b2s = th_byte2sample()
4949
# Read each traceheader
5050
for trace in 1:ntraces
51-
setindex!(headers, read_traceheader(s, th_b2s), trace)
51+
read_traceheader!(s, th_b2s, headers[trace])
5252
skip(s, ns*4)
5353
end
5454

Diff for: src/read/read_con.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function read_con(con::SeisCon, blocks::Array{Int,1};
2424

2525
# Pre-allocate
2626
data = Array{datatype,2}(undef, con.ns, prealloc_traces)
27-
headers = Array{BinaryTraceHeader,1}(undef, prealloc_traces)
27+
headers = [BinaryTraceHeader() for _=1:prealloc_traces]
2828
fh = FileHeader(); set_fileheader!(fh.bfh, :ns, con.ns)
2929
set_fileheader!(fh.bfh, :DataSampleFormat, con.dsf)
3030

@@ -73,7 +73,7 @@ function read_con(con::SeisCon, keys::Array{String,1}, blocks::Array{Int,1};
7373

7474
# Pre-allocate
7575
data = Array{datatype,2}(undef, con.ns, prealloc_traces)
76-
headers = Array{BinaryTraceHeader,1}(undef, prealloc_traces)
76+
headers = [BinaryTraceHeader() for _=1:prealloc_traces]
7777
fh = FileHeader(); set_fileheader!(fh.bfh, :ns, con.ns)
7878
set_fileheader!(fh.bfh, :DataSampleFormat, con.dsf)
7979

Diff for: src/read/read_file.jl

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ Read entire SEGY file from stream 's', only reading the header values in 'keys'.
1818
"""
1919
function read_file(s::IO, keys::Array{String, 1}, warn_user::Bool;
2020
start_byte::Int = 3600, end_byte::Int = position(seekend(s)))
21-
2221
# Read File Header
2322
fh = read_fileheader(s)
2423

@@ -43,16 +42,18 @@ function read_file(s::IO, keys::Array{String, 1}, warn_user::Bool;
4342
ntraces = Int((end_byte - start_byte)/trace_size)
4443

4544
# Preallocate memory
46-
headers = Array{BinaryTraceHeader, 1}(undef, ntraces)
45+
headers = [BinaryTraceHeader() for _ = 1:ntraces]
4746
data = Array{datatype, 2}(undef, fh.bfh.ns, ntraces)
4847
th_b2s = th_byte2sample()
4948

5049
# Read each trace
50+
ref = position(s)
5151
for trace in 1:TRACE_CHUNKSIZE:ntraces
52+
seek(s, (trace - 1) * trace_size + ref)
5253
tracee = min(trace + TRACE_CHUNKSIZE - 1, ntraces)
5354
chunk = length(trace:tracee)*trace_size
5455
sloc = IOBuffer(read(s, chunk))
55-
read_traces!(sloc, fh.bfh, datatype, headers, view(data, :, trace:tracee), trace, keys, th_b2s)
56+
read_traces!(sloc, view(headers, trace:tracee), view(data, :, trace:tracee), keys, th_b2s)
5657
end
5758

5859
return SeisBlock(fh, headers, data)

Diff for: src/read/read_trace.jl

+14-30
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ Use: read_trace!(s::IO,
1212
Reads 'trace' from the current position of stream 's' into 'headers' and
1313
'data'.
1414
"""
15-
function read_traces!(s::IO, fh::BinaryFileHeader, datatype::Type,
16-
headers::AbstractVector{BinaryTraceHeader},
17-
data::AbstractMatrix{<:Union{IBMFloat32, Float32}},
18-
trace::Int, th_byte2sample::Dict{String,Int32})
15+
function read_traces!(s::IO, headers::AbstractVector{BinaryTraceHeader},
16+
data::AbstractMatrix{<:Union{IBMFloat32, Float32}},
17+
th_byte2sample::Dict{String,Int32})
1918

20-
return read_traces!(s, fh, datatype, headers, data, trace, collect(keys(th_byte2sample)), th_byte2sample)
19+
return read_traces!(s, headers, data, collect(keys(th_byte2sample)), th_byte2sample)
2120
end
2221

2322
"""
@@ -33,38 +32,23 @@ Use: read_trace!(s::IO,
3332
Reads 'trace' from the current position of stream 's' into 'headers' and
3433
'data'. Only the header values in 'keys' and read.
3534
"""
36-
function read_traces!(s::IO, fh::BinaryFileHeader,
37-
datatype::Type,
38-
headers::AbstractVector{BinaryTraceHeader},
39-
data::AbstractMatrix{<:Union{IBMFloat32, Float32}},
40-
trace::Int,
41-
keys::Array{String,1},
42-
th_byte2sample::Dict{String,Int32})
35+
function read_traces!(s::IO, headers::AbstractVector{BinaryTraceHeader},
36+
data::AbstractMatrix{DT}, keys::Array{String,1},
37+
th_byte2sample::Dict{String,Int32}) where {DT<:Union{IBMFloat32, Float32}}
4338

4439
ntrace = size(data, 2)
4540
ntrace == 0 && return
41+
swp = swp_func(DT)
42+
tmph = zeros(UInt8, 240)
4643
for trace_loc=0:ntrace-1
4744
# Read trace header
48-
setindex!(headers, read_traceheader(s, keys, th_byte2sample), trace+trace_loc)
49-
45+
read_traceheader!(s, keys, th_byte2sample, headers[trace_loc+1]; th=tmph)
5046
# Read trace
51-
setindex!(data, read_tracedata(s, fh, datatype), :, trace_loc+1)
47+
read!(s, view(data, :, trace_loc+1))
5248
end
49+
map!(swp, data, data)
5350
nothing
5451
end
5552

56-
"""
57-
Read a single trace from current position in stream as Float32
58-
"""
59-
function read_tracedata(s::IO, fh::BinaryFileHeader, dsf::Type{DT}) where {DT<:IBMFloat32}
60-
dummy=Vector{DT}(undef, fh.ns)
61-
read!(s, dummy)
62-
return dummy
63-
end
64-
65-
function read_tracedata(s::IO, fh::BinaryFileHeader, dsf::Type{DT}) where {DT<:Float32}
66-
dummy=Vector{DT}(undef, fh.ns)
67-
read!(s, dummy)
68-
return bswap.(dummy)
69-
end
70-
53+
swp_func(::Type{Float32}) = bswap
54+
swp_func(::Any) = x -> x

Diff for: src/read/read_traceheader.jl

+18-9
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ Use: fileheader = read_fileheader(s::IO; bigendian::Bool = true)
88
99
Returns a binary trace header formed from the current position in the stream 's'.
1010
"""
11-
function read_traceheader(s::IO, th_byte2sample::Dict{String,Int32}; bigendian::Bool = true)
12-
return read_traceheader(s, collect(keys(th_byte2sample)), th_byte2sample; bigendian=bigendian)
11+
function read_traceheader(s::IO, th_byte2sample::Dict{String,Int32}; bigendian::Bool=true, th=zeros(UInt8, 240))
12+
return read_traceheader(s, collect(keys(th_byte2sample)), th_byte2sample; bigendian=bigendian, th=th)
1313
end
1414

1515
"""
@@ -19,23 +19,32 @@ Returns a binary trace header formed from the current position in the stream 's'
1919
header values denoted in 'keys'.
2020
"""
2121
function read_traceheader(s::IO, keys::Array{String,1}, th_byte2sample::Dict{String, Int32};
22-
bigendian::Bool = true)
22+
bigendian::Bool = true, th=zeros(UInt8, 240))
2323

2424
# Initialize binary file header
2525
traceheader = BinaryTraceHeader()
2626

27+
read_traceheader!(s, keys, th_byte2sample, traceheader; bigendian=bigendian, th=th)
28+
return traceheader
29+
end
30+
31+
function read_traceheader!(s::IO, keys::Array{String,1}, th_byte2sample::Dict{String, Int32}, hdr::BinaryTraceHeader;
32+
bigendian::Bool = true, th=zeros(UInt8, 240))
33+
2734
# read full trace header then split
28-
th = read(s, 240)
35+
read!(s, th)
2936

3037
# Read all header values and put in fileheader
3138
for k in keys
3239
sym = Symbol(k)
33-
nb = sizeof(getfield(traceheader, sym))-1
40+
nb = sizeof(getfield(hdr, sym)) - 1
3441
bst = th_byte2sample[k]+1
35-
val = reinterpret(typeof(getfield(traceheader, sym)), th[bst:bst+nb])[1]
42+
val = reinterpret(typeof(getfield(hdr, sym)), th[bst:bst+nb])[1]
3643
bigendian && (val = bswap(val))
37-
setfield!(traceheader, sym, val)
44+
setfield!(hdr, sym, val)
3845
end
39-
40-
return traceheader
46+
nothing
4147
end
48+
49+
read_traceheader!(s::IO, thb::Dict{String, Int32}, hdr::BinaryTraceHeader; be::Bool = true, th=zeros(UInt8, 240)) =
50+
read_traceheader!(s, collect(keys(thb)), thb, hdr; be=be, th=th)

Diff for: src/scan/scan_block.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ function scan_block(buf::IO, mem_block::Int, mem_trace::Int, keys::Array{String,
66
# Calc info about this block
77
startbyte = position(buf) + chunk_start
88
ntraces_block = Int(mem_block/mem_trace)
9-
headers = Array{BinaryTraceHeader,1}(undef, ntraces_block)
9+
headers = [BinaryTraceHeader() for _ = 1:ntraces_block]
1010
count = 0
1111

1212
# Read all headers and record end byte
1313
while !eof(buf) && count<ntraces_block
1414
count += 1
15-
headers[count] = read_traceheader(buf, keys, th_byte2sample)
15+
read_traceheader!(buf, keys, th_byte2sample, headers[count] )
1616
skip(buf, mem_trace-240)
1717
end
1818
endbyte = position(buf) + chunk_start

Diff for: src/scan/scan_file.jl

-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ function scan_file(file::AbstractString, keys::Array{String, 1}, blocksize::Int;
4343
seek(s, 3600)
4444

4545
# For each chunk
46-
@show mem_block, chunksize*MB2B, max_blocks_per_chunk, nblocks_file
4746
for c in 1:max_blocks_per_chunk:nblocks_file
4847

4948
count = scan_chunk!(s, max_blocks_per_chunk, mem_block, mem_trace,

Diff for: src/scan/scan_shots.jl

+7-6
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ function scan_shots!(s::IO, mem_chunk::Int, mem_trace::Int,
99
eof(s) ? (fl_eof=true) : nothing
1010
buf_size = position(seekend(buf)); seekstart(buf)
1111
ntraces = Int(floor(buf_size/mem_trace))
12-
headers = Array{BinaryTraceHeader,1}(undef, ntraces)
12+
headers = [BinaryTraceHeader() for _ = 1:ntraces]
1313

14-
# Get headers from chunk
14+
# Get headers from chunk
15+
th = zeros(UInt8, 240)
1516
for i in 1:ntraces
16-
headers[i] = read_traceheader(buf, keys, SegyIO.th_b2s)
17+
read_traceheader!(buf, keys, SegyIO.th_b2s, headers[i]; th=th)
1718
skip(buf, mem_trace-240)
18-
end
19-
19+
end
20+
2021
# Get all requested header vectors
2122
vals = Dict{String, Array{Int32,1}}()
2223
for k in keys
@@ -29,7 +30,7 @@ function scan_shots!(s::IO, mem_chunk::Int, mem_trace::Int,
2930
sy = vals["SourceY"]
3031
#combo = [[view(sx,i) view(sy,i)] for i in 1:ntraces]
3132
combo = [[sx[i] sy[i]] for i in 1:ntraces]
32-
part = delim_vector(combo,1)
33+
part = delim_vector(combo, 1)
3334
fl_eof ? push!(part, length(combo) + 1) : push!(part, ntraces + 1)
3435

3536
# Summarise each shot

0 commit comments

Comments
 (0)