[Closed] dotNet: how to quickly fill 2D array with values?
It turns out this is very slow (actually the slowest part in my code…):
local a = dotNetObject “System.Double[,]” n m
for i=1 to n do (
for j = 1 to m do (
a.set (i-1) (j-1) myFloat[i][j]
)
)
Any suggestions how to speed this up? Note the two-dimensional array (which I have to use in order to be compatible with a 3rd party dotNet library).
Cheers!
– MartinB
it’s a max to .net object conversion problem… we have decrease number of conversions…
idea #1
a = dotNetObject "System.Double[,]" x y
f = a.set
for i=1 to x do for k=1 to y do f (i-1) (k-1) arr[i][k]
should save a half time
use a c# assembly… the only one really fast way i see.
edited…
btw. i’m not sure that max .net supports multi-dimensional arrays.
at least this simple code:
fn CreateDoubleOpsAssembly =
(
source = ""
source += "using System;
"
source += "public class DoubleOps
"
source += "{
"
source += " public Double[,] Make2DArray(Int32 x, Int32 y)
"
source += " {
"
source += " return new Double[x,y];
"
source += " }
"
source += "}
"
csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.GenerateInMemory = true
compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
compilerResults.CompiledAssembly.CreateInstance "DoubleOps"
)
d = CreateDoubleOpsAssembly()
d.Make2DArray 2 3
doesn’t work
Maybe you can get it to use a jagged array (Double[][]). I haven’t actually checked though.
Well…
dotNet.ValueToDotNetObject #(#(1,2),#(3,4),#(5,6)) (dotNetClass "System.Double[][]")
does work but isn’t compatible with the 3rd party library I am using. That needs a 2D array.
Is there a way to convert one into the other?
– MartinB
It’s a numeric/algebraic math library, written in C#.
I do have the source code, if that matters.
– MartinB
can you post the dll? i’m just very surprised why it works with 2d arrays in max. i can’t pass a 2d array to my any dll. if they can do, we should be able to do it as well
It’s not related to 3ds max at all. It works with 2D arrays because that is the natural C# representation for large matrices, I guess.
– MartinB
fn CreateDoubleOpsAssembly =
(
source = ""
source += "using System;
"
source += "public class DoubleOps
"
source += "{
"
source += " public Int32[] set2DArray(Double[][] array, ref Double[,] doubleArray)
"
source += " {
"
source += " Int32[] size = { array.Length, array[0].Length };
"
source += " for (var k = 0; k < size[0]; k++)
"
source += " {
"
source += " for (var i = 0; i < size[1]; i++) doubleArray[k, i] = array[k][i];
"
source += " }
"
source += " return size;
"
source += " }
"
source += "}
"
csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.GenerateInMemory = true
compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
compilerResults.CompiledAssembly.CreateInstance "DoubleOps"
)
d = CreateDoubleOpsAssembly()
/*
aa = for k=1 to 1000 collect (for i=1 to 1000 collect (random -100.0d0 100.0d0))
--bb = dotnet.valuetodotnetobject aa (dotnetclass "Double[][]")
t1 = timestamp()
m1 = heapfree
dd = dotnetobject "Double[,]" 1000 1000
d.set2DArray aa dd
format "time:% memory:%
" (timestamp() - t1) (m1 - heapfree)
-- time:296 memory:2296L
for k=0 to 4 do for i=0 to 4 do format "[k,i] => %
" (dd.get k i)
*/
I get an error on the line
compilerResults.CompiledAssembly.CreateInstance "DoubleOps"
– Runtime error: dotNet runtime exception: Could not load file or assembly …
blimey ! hardcore, my brain is usually fried by midnight ! I sometimes look at code written in the early hours at a later date and the thought that goes through my head is “wtf was I thinking!!” I’ve used some bizarre logic.