Skip to content

Conversation

@hubgeter
Copy link
Contributor

@hubgeter hubgeter commented Nov 21, 2025

What problem does this PR solve?

Problem Summary:
PR #49688 adds a profile statistics interface for appendDataTime to JNI.
This PR has two main benefits:

  1. it adds this statistical interface to all JniScanner instances;
  2. it changes the previous statistics method for PaimonJniScanner. The old method called System.nanoTime multiple times (rows * columns *2 times), which significantly increased CPU usage and reduced overall performance.

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

@Thearas
Copy link
Contributor

Thearas commented Nov 21, 2025

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@hubgeter
Copy link
Contributor Author

run buildall

@doris-robot
Copy link

TPC-H: Total hot run time: 35174 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 971175304a3fccbddf40f51a7c3e5d9363aaf5ad, data reload: false

------ Round 1 ----------------------------------
q1	17593	5111	4928	4928
q2	2050	333	208	208
q3	10211	1277	733	733
q4	10230	894	370	370
q5	7580	2418	2328	2328
q6	183	170	135	135
q7	929	754	629	629
q8	9358	1339	1125	1125
q9	7080	5341	5340	5340
q10	6825	2212	1814	1814
q11	488	299	282	282
q12	329	372	226	226
q13	17795	3637	3049	3049
q14	234	245	216	216
q15	560	511	504	504
q16	1037	1010	932	932
q17	584	862	365	365
q18	7803	7573	8064	7573
q19	1375	965	597	597
q20	368	343	242	242
q21	4492	3736	2544	2544
q22	1357	1069	1034	1034
Total cold run time: 108461 ms
Total hot run time: 35174 ms

----- Round 2, with runtime_filter_mode=off -----
q1	5209	5024	5253	5024
q2	328	419	334	334
q3	2374	2854	2458	2458
q4	1416	1921	1426	1426
q5	4667	4481	4500	4481
q6	212	169	130	130
q7	2010	1951	1904	1904
q8	2589	2569	2481	2481
q9	7600	7587	7676	7587
q10	3086	3260	2814	2814
q11	585	532	529	529
q12	705	801	628	628
q13	3389	3695	3073	3073
q14	268	289	252	252
q15	529	483	479	479
q16	1012	1025	997	997
q17	1109	1423	1286	1286
q18	7415	7285	7093	7093
q19	752	760	838	760
q20	1939	1974	1821	1821
q21	4716	4404	4272	4272
q22	1070	1046	1007	1007
Total cold run time: 52980 ms
Total hot run time: 50836 ms

@doris-robot
Copy link

TPC-DS: Total hot run time: 187734 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 971175304a3fccbddf40f51a7c3e5d9363aaf5ad, data reload: false

query1	1022	442	398	398
query2	6556	1630	1696	1630
query3	6761	220	221	220
query4	26572	23463	23307	23307
query5	4359	606	466	466
query6	331	227	220	220
query7	4665	493	302	302
query8	310	254	249	249
query9	8692	2580	2590	2580
query10	477	334	316	316
query11	15956	15332	14937	14937
query12	181	124	106	106
query13	1673	550	448	448
query14	11081	9203	9155	9155
query15	198	183	168	168
query16	7305	701	525	525
query17	1226	757	655	655
query18	1980	418	310	310
query19	212	201	177	177
query20	127	123	122	122
query21	214	134	111	111
query22	4102	4026	4173	4026
query23	34075	33055	33175	33055
query24	8457	2377	2354	2354
query25	596	503	459	459
query26	1243	282	169	169
query27	2748	501	356	356
query28	4351	2188	2158	2158
query29	823	603	487	487
query30	296	227	200	200
query31	926	820	715	715
query32	84	73	83	73
query33	589	394	320	320
query34	814	846	518	518
query35	800	862	749	749
query36	946	1012	890	890
query37	119	111	85	85
query38	3626	3528	3459	3459
query39	1480	1423	1412	1412
query40	225	126	121	121
query41	65	62	62	62
query42	124	113	110	110
query43	508	494	461	461
query44	1240	770	770	770
query45	184	181	177	177
query46	896	998	642	642
query47	1793	1794	1703	1703
query48	404	422	330	330
query49	791	490	407	407
query50	655	705	418	418
query51	3876	3952	3915	3915
query52	114	118	102	102
query53	246	272	197	197
query54	326	323	292	292
query55	93	89	85	85
query56	337	344	343	343
query57	1208	1191	1122	1122
query58	300	283	284	283
query59	2568	2634	2552	2552
query60	377	362	344	344
query61	189	190	196	190
query62	813	713	656	656
query63	231	199	202	199
query64	4660	1295	978	978
query65	4045	3950	3937	3937
query66	1196	444	354	354
query67	15554	14984	14991	14984
query68	8162	935	635	635
query69	485	361	285	285
query70	1376	1291	1257	1257
query71	441	331	323	323
query72	5925	4867	4781	4781
query73	647	578	359	359
query74	8933	9126	8711	8711
query75	3497	3339	2800	2800
query76	3407	1136	729	729
query77	734	401	314	314
query78	9995	9483	8891	8891
query79	2277	833	610	610
query80	628	573	498	498
query81	498	257	226	226
query82	484	158	131	131
query83	274	260	259	259
query84	263	109	90	90
query85	948	510	440	440
query86	384	309	287	287
query87	3698	3662	3617	3617
query88	3709	2201	2209	2201
query89	390	327	293	293
query90	1972	213	215	213
query91	175	164	139	139
query92	79	63	61	61
query93	1763	995	678	678
query94	744	464	351	351
query95	409	322	314	314
query96	477	567	274	274
query97	2958	2954	2838	2838
query98	251	209	204	204
query99	1460	1402	1304	1304
Total cold run time: 276434 ms
Total hot run time: 187734 ms

@doris-robot
Copy link

ClickBench: Total hot run time: 27.24 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 971175304a3fccbddf40f51a7c3e5d9363aaf5ad, data reload: false

query1	0.06	0.05	0.05
query2	0.10	0.04	0.05
query3	0.26	0.08	0.08
query4	1.61	0.11	0.11
query5	0.27	0.25	0.26
query6	1.18	0.65	0.64
query7	0.03	0.02	0.03
query8	0.05	0.04	0.04
query9	0.59	0.54	0.51
query10	0.57	0.57	0.58
query11	0.16	0.11	0.12
query12	0.15	0.13	0.12
query13	0.60	0.60	0.60
query14	1.01	0.99	0.98
query15	0.85	0.83	0.83
query16	0.40	0.40	0.40
query17	1.00	1.05	1.06
query18	0.21	0.20	0.19
query19	1.94	1.85	1.84
query20	0.02	0.01	0.01
query21	15.44	0.18	0.13
query22	5.11	0.07	0.05
query23	15.68	0.27	0.10
query24	2.98	0.71	0.28
query25	0.06	0.05	0.06
query26	0.15	0.14	0.12
query27	0.05	0.06	0.06
query28	4.00	1.14	0.94
query29	12.56	3.87	3.16
query30	0.28	0.14	0.11
query31	2.81	0.61	0.40
query32	3.23	0.56	0.47
query33	3.00	3.01	3.12
query34	15.94	5.14	4.54
query35	4.58	4.56	4.60
query36	0.68	0.49	0.48
query37	0.10	0.06	0.07
query38	0.07	0.04	0.04
query39	0.04	0.03	0.02
query40	0.17	0.14	0.13
query41	0.09	0.03	0.03
query42	0.04	0.03	0.04
query43	0.04	0.04	0.03
Total cold run time: 98.16 s
Total hot run time: 27.24 s

@hello-stephen
Copy link
Contributor

FE UT Coverage Report

Increment line coverage `` 🎉
Increment coverage report
Complete coverage report

break;
}
StructLike row = reader.next();
records.add(reader.next());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May this consume more memory? Cause we have to save all records before doing the append?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t think it will consume much memory, because at most there will only be one batch of data at a time. The reason for storing this data before calling append is that I think some data-retrieval methods might be lazily loaded, so I separated the reader.next() call from the append method.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes the statistical time measurement for JNI appendData operations across all JniScanner implementations. Previously, PaimonJniScanner called System.nanoTime() multiple times per batch (rows × columns × 2), which significantly increased CPU usage. The refactoring changes the timing approach to measure once per batch, and extends consistent timing measurement to all JniScanner instances.

Key changes:

  • Refactored Paimon scanners to separate data reading from data appending, enabling batch-level timing measurement
  • Added appendDataTime timing statistics to all JniScanner implementations (MaxCompute, Mock, Iceberg, Hudi, Avro, Trino)
  • Reduced timing overhead from O(rows × columns) System.nanoTime() calls to O(batches) calls

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
TrinoConnectorJniScanner.java Aggregates per-column timing statistics into total appendDataTime in close() method
PaimonSysTableJniScanner.java Refactored to separate record reading (readNextBatch()) from processing, enabling batch-level timing
PaimonJniScanner.java Similar refactoring as PaimonSysTableJniScanner, with batch-level timing measurement
MaxComputeJniScanner.java Added batch-level timing measurement around the data appending loop
MockJniScanner.java Added batch-level timing measurement for test/mock scanner
IcebergSysTableJniScanner.java Refactored to collect records first, then append with batch-level timing
HadoopHudiJniScanner.java Refactored to separate record deserialization from appending, with batch-level timing
AvroJNIScanner.java Refactored with new readNextBatch() method and batch-level timing measurement

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +208 to +216
// for (int i = 0; i < requiredFields.length; i++) {
// Object fieldData = rowRecord.get(requiredFields[i]);
// if (fieldData == null) {
// appendData(i, null);
// } else {
// AvroColumnValue fieldValue = new AvroColumnValue(fieldInspectors[i], fieldData);
// appendData(i, fieldValue);
// }
// }
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented-out code. This code block appears to be old implementation that has been replaced by the refactored version in the getNext() method. Commented code should be removed rather than left in the codebase.

Suggested change
// for (int i = 0; i < requiredFields.length; i++) {
// Object fieldData = rowRecord.get(requiredFields[i]);
// if (fieldData == null) {
// appendData(i, null);
// } else {
// AvroColumnValue fieldValue = new AvroColumnValue(fieldInspectors[i], fieldData);
// appendData(i, fieldValue);
// }
// }

Copilot uses AI. Check for mistakes.
int rows = 0;
private List<InternalRow> readNextBatch() throws IOException {
List<InternalRow> records = new ArrayList<>();
// int rows = 0;
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented-out code. The comment // int rows = 0; serves no purpose and should be deleted.

Suggested change
// int rows = 0;

Copilot uses AI. Check for mistakes.
Comment on lines +170 to 171
List<Object> records = new ArrayList<>();
int numRows = 0;
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The records list is created but remains empty when fields.length == 0 (virtual table case). While this doesn't cause incorrect behavior, it's inefficient to create an unused list. Consider moving the list creation inside the if (fields.length > 0) block to avoid unnecessary allocation.

Suggested change
List<Object> records = new ArrayList<>();
int numRows = 0;
int numRows = 0;
List<Object> records = null;
if (fields.length > 0) {
records = new ArrayList<>();
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants