Choose Language Hide Translation Bar
Highlighted
john_madden
Level V

Namespaces & custom function performance

In creating a library of custom functions, I've noticed a marked difference in performance of the same function code depending on whether the function is in the global namespace or a user-defined namespace. In at least one frustrating  case of mine, the same function takes 7 times as long to execute when it is in a custom namespace, compared to the global namespace.

The difference doesn't matter in many applications, but I am using these functions on tables with 500K to 5M rows; a difference of this magnitude makes the difference between a function that is fine vs. one that is unusable.

Here some JSL that exemplifies the difference:

Names Default to Here(1);

Add Custom Functions(
	globaltest = New Custom Function(
		"Global",
		"test123",
		Function({x, y, z},
			{a, b, c},
			a = x;
			b = y;
			c = z;
			Return(c)
		)
	)
);
Add Custom Functions(
	nstest = New Custom Function(
		"other",
		"test123",
		Function({x, y, z},
			{a, b, c},
			a = x;
			b = y;
			c = z;
			Return(c)
		)
	)
);

For(i = 1, i <= 10000, i++,
	foo = ::test123(i, i, i);
);

For(i = 1, i <= 10000, i++,
	foo = other:test123(i, i, i);
);

On my machine, ::test123() executes in 143 ms, whereas other:test123 takes 343 ms. 

I have some functions that I'd ideally like to implement in a custom namespace or as class methods, but the overhead associated with namespace-qualification makes this untenable.

Have others have noticed this, and are there techniques/considerations that can speed up invocation of namespace-qualified functions?

3 REPLIES 3
Highlighted
john_madden
Level V

Re: Namespaces & custom function performance

Whoops, looking in scripting guide p 896 I found some remarks about this. I should've known to look there first. Biggest tip seems to be to favor expressions over functions if speed is critical. Also, I didn't realize Return() statements slowed things down. Any other tips would be gratefully received.

Highlighted
Craige_Hales
Staff (Retired)

Re: Namespaces & custom function performance

return(), break(), and continue() all have the same behavior. While they make the JSL easier to read and maintain, there is some overhead when they are executed. I'm pretty sure the JSL profiler will point them out if they are the hot spot.

Yes, I've noticed there is a penalty for name spaces as well, but I'm willing to use them for complicated projects. For simple variables that prove to be the hot spot, you can use a copy-in, copy-out strategy like below. (Profile first, don't optimize code that isn't slowing you down!)

The following does almost nothing but exercise the namespace; most code would not see this much penalty for using a namespace. @EvanMcCorkle 

test = New Namespace(
	"test"
);

f = Function( {},
	{i, testx},
	test:x = 0;
	If( useLocal, // speed up by copy-in, copy-out
		testx = test:x;
		For( i = 1, i < 1e6, i += 1,
			testx = testx + 1
		);
		test:x = testx;
	, // no speed up
		For( i = 1, i < 1e6, i += 1,
			test:x = test:x + 1
		);
	);
);
useLocal = 0;
t0 = Tick Seconds();
f();
t1 = Tick Seconds();
Show( useLocal, t1 - t0, test:x );//t1 - t0 = 2.76666666666642;
useLocal = 1;
t0 = Tick Seconds();
f();
t1 = Tick Seconds();
Show( useLocal, t1 - t0, test:x );//t1 - t0 = 0.316666666665697;
Craige
Highlighted
john_madden
Level V

Re: Namespaces & custom function performance

I'll give the in-out strategy a try!!! Thanks Craige!!!!

Article Labels

    There are no labels assigned to this post.