How to replace a multiple iterator Table to speed up computation

I need to create an array of data which resembles to something like this

Table[{i, Sin[j^2*i]}, {j, 2000}, {i, 0., Pi, Pi/10000.}]

where each "row" of the array contains a list of tuples for varying values of the 'j' parameter. The time required for this computation can be calculated by the AbsoluteTiming function, giving

{15.1485, Null}

I succeeded in using functional programming at the first level. This speeds things up. For example, the following code does the same thing as the initial one:

Table[{#1, Sin[j^2 #1]} & /@ Range[0, Pi, Pi/10000.], {j, 2000}]

but is 5 times as fast as the original one. AbsoluteTiming returns

{3.71441, Null}

The size of these tables roughly represents the size of the data that I am currently manipulating (lots of it). Since I noticed that Table is not the most "time-efficient" option, I would like to learn how to construct this kind of table with things like pure functions and slots (which I naively assume leads to faster code).

• Table[{i, Sin[j^2 i]}, {j, 2}, {i, 0., Pi, Pi/100.}]; : Table can take multiple iterators.
– Syed
Sep 17, 2022 at 3:43
• @Syed You are right and I do not know why but I was evaluating a Table with the iterators in the wrong order, which of course was not giving the desired result: Table[{i, Sin[j*i]}, {i, 0., 4 Pi, 4 Pi/100.},{j,2}]. Nevertheless, I have modified the title and updated my question accordingly. Sep 17, 2022 at 3:48
• t1 = Chop@Table[{i, Sin[j*i]}, {j, 2}, {i, 0., 4 Pi, 4 Pi/100.}]; and t2 = Chop@ Outer[{#2, Sin[#1 #2]} & , {1, 2}, Range[0., 4 Pi, 4 Pi/100.]]; are almost identical in timing.
– Syed
Sep 17, 2022 at 4:01
• Table is functional programming. If what you are looking for is to speed up this code, then please edit the question and make that the main topic. Sep 17, 2022 at 7:47
• @Szabolcs I got confused with what functional programming means. You are right, speed is what I am looking for. The question has been edited accordingly. Sep 17, 2022 at 14:35

Set

A=N[Range[2000]];
B=N[Range[0,Pi,Pi/10000.]];

I will compare

method1:=Outer[{#2,Sin[#1^2*#2]}&,A,B];
method2:=Transpose[{ConstantArray[B,Length[A]],
Sin[Outer[Times,A^2,B]]},{3,1,2}];

To check that they give the same output, run

Max[Abs[Flatten[method1-method2]]]

Timing

RepeatedTiming[method1;]