[Closed] enumeratefiles slow for selection, fast for all scene
(
local mapfiles=#()
fn addmap mapfile =
(
local mapfileN=mapfile-- as name
local index=finditem mapfiles mapfileN
if index == 0 do append mapfiles mapfileN
)
mapfiles=#()
--for all scene
start = timestamp()
enumeratefiles addmap
end = timestamp()
format "Enumerate for all scene took % seconds
" ((end-start)/1000.0)
--for selection
start = timestamp()
for node in selection do
enumeratefiles node addmap
end = timestamp()
format "Enumerate for selection took % seconds
" ((end-start)/1000.0)
start = timestamp()
fn Completed sender arg =
(
sender.Dispose();
end = timestamp()
format "Enumerate for selection with BGWorker took % seconds
" ((end-start)/1000.0)
--print mapfiles
)
fn EnumF sender arg =
(
for node in selection do
(
enumeratefiles node addmap --#missing
)
)
fn ScanFiles =
(
local thread = dotnetobject "System.ComponentModel.BackGroundWorker";
dotnet.addeventhandler thread "DoWork" EnumF ;
dotNet.addeventhandler thread "RunWorkerCompleted" Completed;
thread.RunWorkerAsync "selection";
thread.IsBusy;
)
ScanFiles()
--print mapfiles
)
For a scene with 2491 objects selected and 68 texture maps I get such such results:
Enumerate for all scene took 0.081 seconds
Enumerate for selection took 14.262 seconds
Enumerate for selection with BGWorker took 14.54 seconds
It seams that it should work faster for selection, but it soesn’t. If I don’t use BGWorker for selection then UI is become busy for a while. Tell me please, do you have a better solution then me may be…?
Thx in advance!
Yes, it might take longer for selections. Can’t you use usedMaps() instead?
Check out the following tests:
(
local mapfiles, calls
fn addmap mapfile =
(
calls += 1
appendifunique mapfiles mapfile
)
fn RunTests =
(
--ALL NODES
mapfiles=#(); calls=0
st = timestamp(); sh = heapfree
enumeratefiles addmap
format "all:%ms ram:% files:% calls:%
" (timestamp()-st) (sh-heapfree) mapfiles.count calls
--sleep 1; gc()
--SELECTION
mapfiles=#(); calls=0
st = timestamp(); sh = heapfree
for node in selection do enumeratefiles node addmap
format "sel:%ms ram:% files:% calls:%
" (timestamp()-st) (sh-heapfree) mapfiles.count calls
--sleep 1; gc()
mapfiles=#()
st = timestamp(); sh = heapfree
for node in selection do join mapfiles (usedmaps node)
mapfiles = makeuniquearray mapfiles
format "sel:%ms ram:% files:%
" (timestamp()-st) (sh-heapfree) mapfiles.count
)
max create mode
/* TEST 1 */
format "TEST 1
"
delete objects; gc()
map = bitmaptexture filename:"NO_BITMAP"
mat = standard diffusemap:map specularmap:map bumpmap:map opacitymap:map
for j = 1 to 1000 do box lengthsegs:1 widthsegs:1 heightsegs:1 material:mat
max select all
RunTests()
/* TEST 2 */
format "
TEST 2
"
delete objects; gc()
map = bitmaptexture filename:"C:\\MISSING_BITMAP.PNG"
mat = standard diffusemap:map specularmap:map bumpmap:map opacitymap:map
for j = 1 to 1000 do box lengthsegs:1 widthsegs:1 heightsegs:1 material:mat
max select all
RunTests()
/* TEST 3 */
format "
TEST 3
"
delete objects; gc()
tx = bitmap 128 128 color:red filename:"C:\\TEST_BITMAP.PNG"
save tx; close tx
map = bitmaptexture filename:tx.filename
mat = standard diffusemap:map specularmap:map bumpmap:map opacitymap:map
for j = 1 to 1000 do box lengthsegs:1 widthsegs:1 heightsegs:1 material:mat
max select all
RunTests()
deletefile tx.filename
)
I get this results:
TEST 1
– all: 2ms ram:64L files:0 calls:0
– sel:18ms ram:64L files:0 calls:0
– sel:12ms ram:72136L files:0
– TEST 2
– all: 3ms ram:64L files:0 calls:0
– sel:1113ms ram:64L files:0 calls:0
– sel: 22ms ram:72136L files:0
– TEST 3
– all: 2ms ram:184L files:1 calls:1
– sel:206ms ram:960080L files:1 calls:8000
– sel: 51ms ram:136136L files:1
I tested your script on a scene I have with a few thousands objects and a few thousands file assets…enumerating all the assets took ~1.5 seconds, and enumerating random selections of hundreds of objects took ~0.5seconds each time.
Maybe there’s some other issue at play in your scene?
Hey, Jorge! Thank you very much for your post.
Here is an example
all:11ms ram:384L files:4 calls:5
sel:14550ms ram:6567576L files:4 calls:54976
sel:4349ms ram:674384L files:4
for selection it takes really long, but anyway with used maps it’s faster.
Does usedmaps function scan all maps in modifiers, Ies in lights as well? does it work with missed maps?
UsedMaps() should work with modifiers, lights, etc. but AFAIK, they won’t return missing images.
Also, as it works "per instance", in the scene you uploaded it should be a lot faster to scan for materials instead of nodes, as there are 2 materials in the scene but and 1700 nodes. Something like:
for mat in scenematerials do join mapfiles (usedmaps mat)
But then you would need to know if there are no modifiers, and such things.
I don’t remember any mayor problem using it, but I would search on the forum to make sure it will work as you need.