최적화에 도움이 필요합니다안녕하세요,
계산을 최적화하고 싶습니다. Col Formula와 Loop를 모두 시도했지만 둘 다 10k 이상의 행에 더 빠른 것 같지 않습니다.
exe 속도를 비교했는데 둘 다 시간이 매우 오래 걸립니다
Col 공식 = 500.46초;
루프 = 491.70초;
Matrix나 J trans를 이용해 최적화할 수 있는 방법이 있나요?
Names Default To Here( 1 );
dt = Current Data Table();
testColumn = Column( "Test_A" );
slidervalue = 6;
////UsingFormula
start = Tick Seconds();
dt << New Column( "LL_formula",
Numeric,
Continuous,
Formula(
If( Row() < 200, // Skip the first 200 rows
.
,
current_device = :DeviceNumber; // Get the current site number
current_site = :SiteNumber;
// Get the indices of rows that match the current SiteNumber
matching_rows = Where( :DeviceNumber == current_device | :SiteNumber == current_site );
// Determine the start and end positions for the moving window
start_row = Max( 1, Row() - 199 );
end_row = Row();
// Get the moving window data for matching rows
m = Subscript( Expr( testColumn ), matching_rows[Loc( matching_rows >= start_row & matching_rows <= end_row )] );
//m = testColumn[Max( 1, Row() - 199 ) :: Row()];
// Calculate the quantiles and IQR
q1 = Quantile( 0.25, m );
q3 = Quantile( 0.75, m );
// Calculate the lower limit using the sigma function
q1 - (q3 - q1) * (slidervalue - 0.675) / 1.35;
)
)
);
dt << New Column( "UL_formula",
Numeric,
Continuous,
Formula(
If( Row() < 200,
., // Skip the first 200 rows
// Get the moving window data for matching rows
current_device = :DeviceNumber; // Get the current site number
current_site = :SiteNumber;
// Get the indices of rows that match the current SiteNumber
matching_rows = Where( :DeviceNumber == current_device | :SiteNumber == current_site );
start_row = Max( 1, Row() - 199 );
end_row = Row();
m = Subscript( Expr( testColumn ), matching_rows[Loc( matching_rows >= start_row & matching_rows <= end_row )] );
//m = testColumn[Max( 1, Row() - 199 ) :: Row()];
// Calculate the quantiles and IQR
q1 = Quantile( 0.25, m );
q3 = Quantile( 0.75, m );
// Calculate the upper limit using the sigma function
q3 + (q3 - q1) * (slidervalue - 0.675) / 1.35;
)
)
);
end = Tick Seconds();
Show( end - start );
///UsingLoop
start2 = Tick Seconds();
llColX = dt << New Column( "LL_loop", Numeric );
ulColX = dt << New Column( "UL_loop", Numeric );
For Each Row(
dt,
If( Row() < 200,
.,
// Skip the first 200 rows
current_device = :DeviceNumber[Row()]; // Get the current site number
current_site = :SiteNumber[Row()];
// Get the indices of rows that match the current SiteNumber
matching_rows = Where( :DeviceNumber == current_device | :SiteNumber == current_site );
// Determine the start and end positions for the moving window
start_row = Max( 1, Row() - 199 );
end_row = Row();
// Get the moving window data for matching rows
m2 = Subscript( testColumn, matching_rows[Loc( matching_rows >= start_row & matching_rows <= end_row )] );
//m = testColumn[Max( 1, Row() - 199 ) :: Row()];
// Calculate the quantiles and IQR
q1 = Quantile( 0.25, m2 );
q3 = Quantile( 0.75, m2 );
// Calculate the lower limit using the sigma function
llColX[Row()] = q1 - (q3 - q1) * (slidervalue - 0.675) / 1.35;
);
If( Row() < 200,
., // Skip the first 200 rows
// Get the moving window data for matching rows
current_device = :DeviceNumber[Row()]; // Get the current site number
current_site = :SiteNumber[Row()];
// Get the indices of rows that match the current SiteNumber
matching_rows = Where( :DeviceNumber == current_device | :SiteNumber == current_site );
start_row = Max( 1, Row() - 199 );
end_row = Row();
m = Subscript( testColumn, matching_rows[Loc( matching_rows >= start_row & matching_rows <= end_row )] );
//m = testColumn[Max( 1, Row() - 199 ) :: Row()];
// Calculate the quantiles and IQR
q1 = Quantile( 0.25, m );
q3 = Quantile( 0.75, m );
// Calculate the upper limit using the sigma function
ulColX[Row()] = q3 + (q3 - q1) * (slidervalue - 0.675) / 1.35;
);
);
end2 = Tick Seconds();
Show( end2 - start2 );
자동화 및 스크립팅Re: 최적화에 도움이 필요합니다먼저 시도할 것은 << 데이터 업데이트 시작 및 << 데이터 업데이트 종료를 사용하여 개인/보이지 않는 테이블을 활용하는 것입니다. 이를 시도한 후에는 다른 방법으로 전환하는 것이 좋습니다.
Re: 최적화에 도움이 필요합니다JMP의 디버거와 프로파일러를 사용하면 스크립트가 어디에서 가장 많은 시간을 소비하는지 확인할 수 있습니다.
Re: 최적화에 도움이 필요합니다begin/end 데이터 업데이트를 사용해 보았지만 더 나빠졌습니다.
총 시간 : 780.73초
Names Default To Here( 1 );
dt = Current Data Table();
testColumn = Column( "Test_A" );
slidervalue = 6;
///UsingLoop
start2 = Tick Seconds();
llColX = dt << New Column( "LL_loop", Numeric );
ulColX = dt << New Column( "UL_loop", Numeric );
dt << show window( 0 );
dt << begin data update;
For Each Row(
dt,
If( Row() < 200,
.,
// Skip the first 200 rows
current_device = :DeviceNumber[Row()]; // Get the current site number
current_site = :SiteNumber[Row()];
// Get the indices of rows that match the current SiteNumber
matching_rows = Where( :DeviceNumber == current_device | :SiteNumber == current_site );
// Determine the start and end positions for the moving window
start_row = Max( 1, Row() - 199 );
end_row = Row();
// Get the moving window data for matching rows
m2 = Subscript( testColumn, matching_rows[Loc( matching_rows >= start_row & matching_rows <= end_row )] );
//m = testColumn[Max( 1, Row() - 199 ) :: Row()];
// Calculate the quantiles and IQR
q1 = Quantile( 0.25, m2 );
q3 = Quantile( 0.75, m2 );
// Calculate the lower limit using the sigma function
llColX[Row()] = q1 - (q3 - q1) * (slidervalue - 0.675) / 1.35;
);
If( Row() < 200,
., // Skip the first 200 rows
// Get the moving window data for matching rows
current_device = :DeviceNumber[Row()]; // Get the current site number
current_site = :SiteNumber[Row()];
// Get the indices of rows that match the current SiteNumber
matching_rows = Where( :DeviceNumber == current_device | :SiteNumber == current_site );
start_row = Max( 1, Row() - 199 );
end_row = Row();
m = Subscript( testColumn, matching_rows[Loc( matching_rows >= start_row & matching_rows <= end_row )] );
//m = testColumn[Max( 1, Row() - 199 ) :: Row()];
// Calculate the quantiles and IQR
q1 = Quantile( 0.25, m );
q3 = Quantile( 0.75, m );
// Calculate the upper limit using the sigma function
ulColX[Row()] = q3 + (q3 - q1) * (slidervalue - 0.675) / 1.35;
);
);
dt << end data update;
end2 = Tick Seconds();
Show( end2 - start2 );Re: 최적화에 도움이 필요합니다아직 개선할 수 있는 부분이 있지만 내 PC에서는 10~15초가 걸렸습니다.
Names Default To Here(1);
dt = Open("$DOWNLOADS/sample_table.jmp");
slidervalue = 6;
start2 = Tick Seconds();
ds = dt[0, "DeviceNumber"];
ss = dt[0, "SiteNumber"];
m1 = J(1, N Rows(dt), .);
m2 = J(1, N Rows(dt), .);
For Each Row(dt,
If(Row() < 200,
.
,
d = :DeviceNumber[Row()];
s = :SiteNumber[Row()];
rs = (Row() - 199)::Row();
d1 = ds[rs];
s1 = ss[rs];
r = where(s1 == s | d1 == d);
vals = dt[rs[r], "Test_A"];
q1 = Quantile(0.25, vals);
q3 = Quantile(0.75, vals);
m1[Row()] = q1 - (q3 - q1) * (slidervalue - 0.675) / 1.35;
m2[Row()] = q3 + (q3 - q1) * (slidervalue - 0.675) / 1.35;
);
);
llColX = dt << New Column("LL_loop1", Numeric, Continuous, Values(m1));
llColX = dt << New Column("UL_loop2", Numeric, Continuous, Values(m2));
end2 = Tick Seconds();
Show(end2 - start2);