public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH V1][RFC] t/perf/p3400: speed up setup using fast-import
@ 2026-01-26 16:56 Tian Yuchen
  2026-01-26 17:06 ` Tian Yuchen
  2026-01-28 16:07 ` [PATCH v2] " Tian Yuchen
  0 siblings, 2 replies; 14+ messages in thread
From: Tian Yuchen @ 2026-01-26 16:56 UTC (permalink / raw)
  To: git; +Cc: gitster

The setup phase in 't/perf/p3400-rebase.sh' generates 100 commits to
simulate a noisy history. It currently uses a shell loop that invokes
'git add', 'git commit', 'test_seq', and 'sort' in each iteration.
This makes the whole process slow.

Optimize the setup by using 'git fast-import' to generate the commit
history in a single stream. Additionally, pre-compute the forward and
reversed file contents to avoid repetitive execution of 'seq' and 'sort'.

Performance enhancement:
  Before: 29.045s
  After:  18.081s

Measured on Lenovo Yoga 2020, Ubuntu 24.04.

Signed-off-by: Tian Yuchen <a3205153416@gmail.com>
---
 t/perf/p3400-rebase.sh | 53 +++++++++++++++++++++++++++++-------------
 1 file changed, 37 insertions(+), 16 deletions(-)

diff --git a/t/perf/p3400-rebase.sh b/t/perf/p3400-rebase.sh
index e6b0277729..9251a09b4f 100755
--- a/t/perf/p3400-rebase.sh
+++ b/t/perf/p3400-rebase.sh
@@ -9,25 +9,46 @@ test_expect_success 'setup rebasing on top of a lot of changes' '
 	git checkout -f -B base &&
 	git checkout -B to-rebase &&
 	git checkout -B upstream &&
-	for i in $(test_seq 100)
-	do
-		# simulate huge diffs
-		echo change$i >unrelated-file$i &&
-		test_seq 1000 >>unrelated-file$i &&
-		git add unrelated-file$i &&
-		test_tick &&
-		git commit -m commit$i unrelated-file$i &&
-		echo change$i >unrelated-file$i &&
-		test_seq 1000 | sort -nr >>unrelated-file$i &&
-		git add unrelated-file$i &&
-		test_tick &&
-		git commit -m commit$i-reverse unrelated-file$i ||
-		return 1
-	done &&
+
+	test_seq 1000 >content_fwd &&
+	test_seq 1000 | sort -nr >content_rev &&
+
+	(
+		for i in $(test_seq 100)
+		do
+			echo "commit refs/heads/upstream" &&
+			echo "committer WGYDY <author@mock.com> $i +0000" &&
+			echo "data <<EOF" &&
+			echo "commit$i" &&
+			echo "EOF" &&
+			
+			if test "$i" = 1; then
+				echo "from refs/heads/upstream^0"
+			fi &&
+
+			echo "M 100644 inline unrelated-file$i" &&
+			echo "data <<EOF" &&
+			echo "change$i" &&
+			cat content_fwd &&
+			echo "EOF" &&
+
+			echo "commit refs/heads/upstream" &&
+			echo "committer WGYDY <author@mock.com> $i +0000" &&
+			echo "data <<EOF" &&
+			echo "commit$i-reversed" &&
+			echo "EOF" &&
+			echo "M 100644 inline unrelated-file$i" &&
+			echo "data <<EOF" &&
+			echo "change$i" &&
+			cat content_rev &&
+			echo "EOF" || return 1
+		done
+	) | git fast-import &&
+	
+	git checkout -f upstream &&
 	git checkout to-rebase &&
 	test_commit our-patch interesting-file
 '
-
 test_perf 'rebase on top of a lot of unrelated changes' '
 	git rebase --onto upstream HEAD^ &&
 	git rebase --onto base HEAD^
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH V1][RFC] t/perf/p3400: speed up setup using fast-import
  2026-01-26 16:56 [PATCH V1][RFC] t/perf/p3400: speed up setup using fast-import Tian Yuchen
@ 2026-01-26 17:06 ` Tian Yuchen
  2026-01-28  4:33   ` Tian Yuchen
  2026-01-28 16:07 ` [PATCH v2] " Tian Yuchen
  1 sibling, 1 reply; 14+ messages in thread
From: Tian Yuchen @ 2026-01-26 17:06 UTC (permalink / raw)
  To: git; +Cc: gitster

I noticed that while the setup phase is much faster (as shown in the commit
message), the actual rebase performance test regressed slightly by about 3
seconds (from ~2s to ~5s). I don't quite understand what led to this outcome.

Additionally, I haven't delved deeply into the technical details of
`git fast-import`,
and I'm not entirely sure if my approach is reasonable and compliant with the
specifications.

I would greatly appreciate any guidance from those knowledgeable in these
area!

Regards,
Yuchen

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V1][RFC] t/perf/p3400: speed up setup using fast-import
  2026-01-26 17:06 ` Tian Yuchen
@ 2026-01-28  4:33   ` Tian Yuchen
  2026-01-28 15:25     ` Tian Yuchen
  0 siblings, 1 reply; 14+ messages in thread
From: Tian Yuchen @ 2026-01-28  4:33 UTC (permalink / raw)
  To: git

Tian Yuchen <a3205153416@gmail.com> writes:
>
> I noticed that while the setup phase is much faster (as shown in the commit
> message), the actual rebase performance test regressed slightly by about 3
> seconds (from ~2s to ~5s). I don't quite understand what led to this outcome.
>
> Additionally, I haven't delved deeply into the technical details of
> `git fast-import`,
> and I'm not entirely sure if my approach is reasonable and compliant with the
> specifications.
>
> I would greatly appreciate any guidance from those knowledgeable in these
> area!
>
> Regards,
> Yuchen

I highly suspect that git fast-import generate the packfile that is NOT delta
compressed. According to git fast-import documentation:

>...For this reason it is strongly recommended that users repack the repository with
>'git repack -a -d' after fast-import completes, allowing Git to reorganize the packfiles
>for faster data access...

Could this be the reason why it's even slower than handling “loose
objects”? I'm working
on it currently.

Regards,
Yuchen

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V1][RFC] t/perf/p3400: speed up setup using fast-import
  2026-01-28  4:33   ` Tian Yuchen
@ 2026-01-28 15:25     ` Tian Yuchen
  0 siblings, 0 replies; 14+ messages in thread
From: Tian Yuchen @ 2026-01-28 15:25 UTC (permalink / raw)
  To: git

>...For this reason it is strongly recommended that users repack the repository with
>'git repack -a -d' after fast-import completes, allowing Git to reorganize the packfiles
>for faster data access...

After adding 'git repack -a -d', the time does changed:
                original(no change)        patch v1          NEW
     real           29.845                       18.081           22.231
rebase            13.34                         14.94            12.78

It seems that the 'git repack -a -d' line does reduce runtime.
However, the total duration
has seen a noticeable performance regression. I'm still trying to figure it out.

With regards,
Yuchen

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2] t/perf/p3400: speed up setup using fast-import
  2026-01-26 16:56 [PATCH V1][RFC] t/perf/p3400: speed up setup using fast-import Tian Yuchen
  2026-01-26 17:06 ` Tian Yuchen
@ 2026-01-28 16:07 ` Tian Yuchen
  2026-01-30  6:41   ` Johannes Sixt
                     ` (2 more replies)
  1 sibling, 3 replies; 14+ messages in thread
From: Tian Yuchen @ 2026-01-28 16:07 UTC (permalink / raw)
  To: git; +Cc: gitster

The setup phase in 't/perf/p3400-rebase.sh' generates 100 commits to
simulate a noisy history. It currently uses a shell loop that invokes
'git add', 'git commit', 'test_seq', and 'sort' in each iteration.
This incurs significant overhead due to repeated process spawning.

Optimize the setup by using 'git fast-import' to generate the commit
history in a single stream. Additionally, pre-compute the forward and
reversed file contents to avoid repetitive execution of 'seq' and 'sort'.

To ensure the test measures rebase performance against a consistent
object layout (rather than the suboptimal pack/loose objects created
by the raw import), perform a full repack (`git repack -a -d`) at the
end of the setup.

This reduces the setup time significantly while maintaining the validity
of the subsequent performance tests.

Performance enhancement:
          Real         Rebase
  Before: 29.045s      13.34s
  After:  22.231s      12.78s

Measured on Lenovo Yoga 2020, Ubuntu 24.04.

Signed-off-by: Tian Yuchen <a3205153416@gmail.com>
---

Changes since v1:
- Added 'git repack -a -d' at the end of the setup phase.
- This fixes a performance regression observed in the subsequent rebase
  test, ensuring the object layout is normalized before testing.
- Updated setup timing in the commit message to reflect the repack overhead.

 t/perf/p3400-rebase.sh | 54 +++++++++++++++++++++++++++++-------------
 1 file changed, 38 insertions(+), 16 deletions(-)

diff --git a/t/perf/p3400-rebase.sh b/t/perf/p3400-rebase.sh
index e6b0277729..9f4251aed6 100755
--- a/t/perf/p3400-rebase.sh
+++ b/t/perf/p3400-rebase.sh
@@ -9,25 +9,47 @@ test_expect_success 'setup rebasing on top of a lot of changes' '
 	git checkout -f -B base &&
 	git checkout -B to-rebase &&
 	git checkout -B upstream &&
-	for i in $(test_seq 100)
-	do
-		# simulate huge diffs
-		echo change$i >unrelated-file$i &&
-		test_seq 1000 >>unrelated-file$i &&
-		git add unrelated-file$i &&
-		test_tick &&
-		git commit -m commit$i unrelated-file$i &&
-		echo change$i >unrelated-file$i &&
-		test_seq 1000 | sort -nr >>unrelated-file$i &&
-		git add unrelated-file$i &&
-		test_tick &&
-		git commit -m commit$i-reverse unrelated-file$i ||
-		return 1
-	done &&
+
+	test_seq 1000 >content_fwd &&
+	test_seq 1000 | sort -nr >content_rev &&
+
+	(
+		for i in $(test_seq 100)
+		do
+			echo "commit refs/heads/upstream" &&
+			echo "committer WGYDY <author@mock.com> $i +0000" &&
+			echo "data <<EOF" &&
+			echo "commit$i" &&
+			echo "EOF" &&
+			
+			if test "$i" = 1; then
+				echo "from refs/heads/upstream^0"
+			fi &&
+
+			echo "M 100644 inline unrelated-file$i" &&
+			echo "data <<EOF" &&
+			echo "change$i" &&
+			cat content_fwd &&
+			echo "EOF" &&
+
+			echo "commit refs/heads/upstream" &&
+			echo "committer WGYDY <author@mock.com> $i +0000" &&
+			echo "data <<EOF" &&
+			echo "commit$i-reversed" &&
+			echo "EOF" &&
+			echo "M 100644 inline unrelated-file$i" &&
+			echo "data <<EOF" &&
+			echo "change$i" &&
+			cat content_rev &&
+			echo "EOF" || return 1
+		done
+	) | git fast-import &&
+
+	git repack -a -d &&
+	git checkout -f upstream &&
 	git checkout to-rebase &&
 	test_commit our-patch interesting-file
 '
-
 test_perf 'rebase on top of a lot of unrelated changes' '
 	git rebase --onto upstream HEAD^ &&
 	git rebase --onto base HEAD^
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] t/perf/p3400: speed up setup using fast-import
  2026-01-28 16:07 ` [PATCH v2] " Tian Yuchen
@ 2026-01-30  6:41   ` Johannes Sixt
  2026-01-30  9:55     ` Johannes Sixt
  2026-01-30 16:27     ` Junio C Hamano
  2026-01-30 14:31   ` Phillip Wood
  2026-01-30 16:29   ` [PATCH v3] " Tian Yuchen
  2 siblings, 2 replies; 14+ messages in thread
From: Johannes Sixt @ 2026-01-30  6:41 UTC (permalink / raw)
  To: Tian Yuchen; +Cc: gitster, git

Am 28.01.26 um 17:07 schrieb Tian Yuchen:
> +	test_seq 1000 >content_fwd &&
> +	test_seq 1000 | sort -nr >content_rev &&

Remove another pipe with

	sort -nr content_fwd >content_rev &&

> +
> +	(
> +		for i in $(test_seq 100)
> +		do
> +			...
> +			cat content_rev &&
> +			echo "EOF" || return 1

This is an incorrect use of `return` outside a function. This must be
`|| exit 1` (or just `|| exit`) to actually break out of the loop.

Of course, the error code is ignored, because it is in the upstream of a
pipe, so in order to fail the complete command, it would be necessary
that the original error left an incorrect fast-import stream such that
the down-stream `git fast-import` fails. Otherwise, the entire command
can complete successfully in an unexpected way.

Maybe instead of a pipe, dump the stream into a temporary file, so that
the loop's exit code can be captured?

> +		done
> +	) | git fast-import &&
-- Hannes


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] t/perf/p3400: speed up setup using fast-import
  2026-01-30  6:41   ` Johannes Sixt
@ 2026-01-30  9:55     ` Johannes Sixt
  2026-01-30 16:27     ` Junio C Hamano
  1 sibling, 0 replies; 14+ messages in thread
From: Johannes Sixt @ 2026-01-30  9:55 UTC (permalink / raw)
  To: Tian Yuchen; +Cc: gitster, git

Am 30.01.26 um 07:41 schrieb Johannes Sixt:
> Am 28.01.26 um 17:07 schrieb Tian Yuchen:
>> +
>> +	(
>> +		for i in $(test_seq 100)
>> +		do
>> +			...
>> +			cat content_rev &&
>> +			echo "EOF" || return 1
> 
> This is an incorrect use of `return` outside a function. This must be
> `|| exit 1` (or just `|| exit`) to actually break out of the loop.

I am wrong here, because my earlier tests were too narrow. This use of
`return` actually does work as intended, because it happens inside a
function. Neither the subshell nor being in the upstream of a pipe
negates this fact.

The rest of the comment still stands, though.

> Of course, the error code is ignored, because it is in the upstream of a
> pipe, so in order to fail the complete command, it would be necessary
> that the original error left an incorrect fast-import stream such that
> the down-stream `git fast-import` fails. Otherwise, the entire command
> can complete successfully in an unexpected way.
> 
> Maybe instead of a pipe, dump the stream into a temporary file, so that
> the loop's exit code can be captured?
> 
>> +		done
>> +	) | git fast-import &&
-- Hannes


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] t/perf/p3400: speed up setup using fast-import
  2026-01-28 16:07 ` [PATCH v2] " Tian Yuchen
  2026-01-30  6:41   ` Johannes Sixt
@ 2026-01-30 14:31   ` Phillip Wood
  2026-01-30 15:40     ` Tian Yuchen
  2026-01-30 16:29   ` [PATCH v3] " Tian Yuchen
  2 siblings, 1 reply; 14+ messages in thread
From: Phillip Wood @ 2026-01-30 14:31 UTC (permalink / raw)
  To: Tian Yuchen, git; +Cc: gitster, Johannes Sixt

On 28/01/2026 16:07, Tian Yuchen wrote:
> The setup phase in 't/perf/p3400-rebase.sh' generates 100 commits to
> simulate a noisy history. It currently uses a shell loop that invokes
> 'git add', 'git commit', 'test_seq', and 'sort' in each iteration.
> This incurs significant overhead due to repeated process spawning.
> 
> Optimize the setup by using 'git fast-import' to generate the commit
> history in a single stream. Additionally, pre-compute the forward and
> reversed file contents to avoid repetitive execution of 'seq' and 'sort'.
> 
> To ensure the test measures rebase performance against a consistent
> object layout (rather than the suboptimal pack/loose objects created
> by the raw import), perform a full repack (`git repack -a -d`) at the
> end of the setup.
> 
> This reduces the setup time significantly while maintaining the validity
> of the subsequent performance tests.
> 
> Performance enhancement:
>            Real         Rebase
>    Before: 29.045s      13.34s
>    After:  22.231s      12.78s

That's a nice speedup in the test setup

> diff --git a/t/perf/p3400-rebase.sh b/t/perf/p3400-rebase.sh
> index e6b0277729..9f4251aed6 100755
> --- a/t/perf/p3400-rebase.sh
> +++ b/t/perf/p3400-rebase.sh
> @@ -9,25 +9,47 @@ test_expect_success 'setup rebasing on top of a lot of changes' '
>   	git checkout -f -B base &&
>   	git checkout -B to-rebase &&
>   	git checkout -B upstream &&
> -	for i in $(test_seq 100)
> -	do
> -		# simulate huge diffs
> -		echo change$i >unrelated-file$i &&
> -		test_seq 1000 >>unrelated-file$i &&
> -		git add unrelated-file$i &&
> -		test_tick &&
> -		git commit -m commit$i unrelated-file$i &&
> -		echo change$i >unrelated-file$i &&
> -		test_seq 1000 | sort -nr >>unrelated-file$i &&
> -		git add unrelated-file$i &&
> -		test_tick &&
> -		git commit -m commit$i-reverse unrelated-file$i ||
> -		return 1
> -	done &&
> +
> +	test_seq 1000 >content_fwd &&
> +	test_seq 1000 | sort -nr >content_rev &&
> +
> +	(
> +		for i in $(test_seq 100)
> +		do
> +			echo "commit refs/heads/upstream" &&
> +			echo "committer WGYDY <author@mock.com> $i +0000" &&

You can keep the same author and committer as the original with

	test_tick &&
	echo "author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE" &&
	echo "committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 
$GIT_COMMITTER_DATE" &&

here and below

> +			echo "data <<EOF" &&
> +			echo "commit$i" &&
> +			echo "EOF" &&
> +			
> +			if test "$i" = 1; then
> +				echo "from refs/heads/upstream^0"
> +			fi &&
> +
> +			echo "M 100644 inline unrelated-file$i" &&
> +			echo "data <<EOF" &&
> +			echo "change$i" &&
> +			cat content_fwd &&
> +			echo "EOF" &&
> +
> +			echo "commit refs/heads/upstream" &&
> +			echo "committer WGYDY <author@mock.com> $i +0000" &&
> +			echo "data <<EOF" &&
> +			echo "commit$i-reversed" &&

The commit message in the original is "commit$i-reverse", not "reversed"

> +			echo "EOF" &&
> +			echo "M 100644 inline unrelated-file$i" &&
> +			echo "data <<EOF" &&
> +			echo "change$i" &&
> +			cat content_rev &&
> +			echo "EOF" || return 1
> +		done

As Johannes pointed out we'll ignore the any failure above. We can 
address that by adding "echo done" here and adding "--done" to "git 
fast-import" below. That will cause "git fast-import" to fail because if 
there is an error in the loop as the last line of input to fast-import 
will not be "done"

Thanks

Phillip

> +	) | git fast-import &&
> +
> +	git repack -a -d &&
> +	git checkout -f upstream &&
>   	git checkout to-rebase &&
>   	test_commit our-patch interesting-file
>   '
> -
>   test_perf 'rebase on top of a lot of unrelated changes' '
>   	git rebase --onto upstream HEAD^ &&
>   	git rebase --onto base HEAD^


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] t/perf/p3400: speed up setup using fast-import
  2026-01-30 14:31   ` Phillip Wood
@ 2026-01-30 15:40     ` Tian Yuchen
  0 siblings, 0 replies; 14+ messages in thread
From: Tian Yuchen @ 2026-01-30 15:40 UTC (permalink / raw)
  To: phillip.wood; +Cc: git, gitster, Johannes Sixt

Hi Johannes, Hi Phillip,

Thanks a lot for the detailed review and the great suggestions!

@Johannes: I will adopt the 'sort -nr content_fwd' optimization to
save a process.

@Phillip: Your point about the pipe swallowing the exit code is very
insightful. I will
 implement the '--done' protocol to ensure any failure in the loop
causes the test to fail.

I will also update the author/committer generation to use test_tick
and the standard
environment variables, and fix the "reversed" typo.

I will prepare and send a v3 patch shortly incorporating these changes.

Thanks,
Tian Yuchen

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] t/perf/p3400: speed up setup using fast-import
  2026-01-30  6:41   ` Johannes Sixt
  2026-01-30  9:55     ` Johannes Sixt
@ 2026-01-30 16:27     ` Junio C Hamano
       [not found]       ` <b6f12614-ecc1-4d37-ac4c-070925054f28@gmail.com>
  1 sibling, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2026-01-30 16:27 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Tian Yuchen, git

Johannes Sixt <j6t@kdbg.org> writes:

> Am 28.01.26 um 17:07 schrieb Tian Yuchen:
>> +	test_seq 1000 >content_fwd &&
>> +	test_seq 1000 | sort -nr >content_rev &&
>
> Remove another pipe with
>
> 	sort -nr content_fwd >content_rev &&

I agree with the outcome (i.e., we do not run test_seq twice) but
not necessarily with the motivation (i.e., we do not assume test_seq
may fail and care about its failure code, so no need to avoid pipes
for the sake of avoiding pipes).

>> +	(
>> +		for i in $(test_seq 100)
>> +		do
>> +			...
>> +			cat content_rev &&
>> +			echo "EOF" || return 1
>
> This is an incorrect use of `return` outside a function. This must be
> `|| exit 1` (or just `|| exit`) to actually break out of the loop.

Good.

> Of course, the error code is ignored, because it is in the upstream of a
> pipe, so in order to fail the complete command, it would be necessary
> that the original error left an incorrect fast-import stream such that
> the down-stream `git fast-import` fails. Otherwise, the entire command
> can complete successfully in an unexpected way.
>
> Maybe instead of a pipe, dump the stream into a temporary file, so that
> the loop's exit code can be captured?

I like this suggestion.  A temporary file, unless it is excessively
large, has an additional advantage that it allows you to inspect
after "git fast-import" dies on it.

>> +		done
>> +	) | git fast-import &&
> -- Hannes

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3] t/perf/p3400: speed up setup using fast-import
  2026-01-28 16:07 ` [PATCH v2] " Tian Yuchen
  2026-01-30  6:41   ` Johannes Sixt
  2026-01-30 14:31   ` Phillip Wood
@ 2026-01-30 16:29   ` Tian Yuchen
  2026-01-30 17:01     ` [PATCH v4] " Tian Yuchen
  2026-01-30 17:10     ` [PATCH v3] " Junio C Hamano
  2 siblings, 2 replies; 14+ messages in thread
From: Tian Yuchen @ 2026-01-30 16:29 UTC (permalink / raw)
  To: git; +Cc: gitster, j6t, phillip.wood123

The setup phase in 't/perf/p3400-rebase.sh' generates 100 commits to
simulate a noisy history. It currently uses a shell loop that invokes
'git add', 'git commit', 'test_seq', and 'sort' in each iteration.
This incurs significant overhead due to repeated process spawning.

Optimize the setup by using 'git fast-import' to generate the commit
history in a single stream. Additionally, pre-compute the forward and
reversed file contents to avoid repetitive execution of 'seq' and 'sort'.

To ensure the test measures rebase performance against a consistent
object layout (rather than the suboptimal pack/loose objects created
by the raw import), perform a full repack (`git repack -a -d`) at the
end of the setup.

This reduces the setup time significantly while maintaining the validity
of the subsequent performance tests.

Performance enhancement (Average value of 5 tests):
           Real        Rebase
  Before: 29.045s      13.34s
  After:  22.431s      12.98s

Measured on Lenovo Yoga 2020, Ubuntu 24.04.

Signed-off-by: Tian Yuchen <a3205153416@gmail.com>
---

Changes since v2:
- Optimized `content_rev` generation by sorting `content_fwd` directly (Johannes Sixt).
- Used `test_tick` and standard `$GIT_COMMITTER_*` variables for consistency (Phillip Wood).
- Fixed typo "reversed" -> "reverse" to match original test (Phillip Wood).
- Added "done" command and used `git fast-import --done` to prevent errors in the loop being ignored by the pipe (Phillip Wood).

 t/perf/p3400-rebase.sh | 56 ++++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 16 deletions(-)

diff --git a/t/perf/p3400-rebase.sh b/t/perf/p3400-rebase.sh
index e6b0277729..6bb58282d6 100755
--- a/t/perf/p3400-rebase.sh
+++ b/t/perf/p3400-rebase.sh
@@ -9,25 +9,49 @@ test_expect_success 'setup rebasing on top of a lot of changes' '
 	git checkout -f -B base &&
 	git checkout -B to-rebase &&
 	git checkout -B upstream &&
-	for i in $(test_seq 100)
-	do
-		# simulate huge diffs
-		echo change$i >unrelated-file$i &&
-		test_seq 1000 >>unrelated-file$i &&
-		git add unrelated-file$i &&
-		test_tick &&
-		git commit -m commit$i unrelated-file$i &&
-		echo change$i >unrelated-file$i &&
-		test_seq 1000 | sort -nr >>unrelated-file$i &&
-		git add unrelated-file$i &&
-		test_tick &&
-		git commit -m commit$i-reverse unrelated-file$i ||
-		return 1
-	done &&
+
+	test_seq 1000 >content_fwd &&
+	sort -nr content_fwd >content_rev &&
+
+	(
+		for i in $(test_seq 100)
+		do
+			test_tick &&
+			echo "commit refs/heads/upstream" &&
+			echo "committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" &&
+			echo "data <<EOF" &&
+			echo "commit$i" &&
+			echo "EOF" &&
+			
+			if test "$i" = 1; then
+				echo "from refs/heads/upstream^0"
+			fi &&
+
+			echo "M 100644 inline unrelated-file$i" &&
+			echo "data <<EOF" &&
+			echo "change$i" &&
+			cat content_fwd &&
+			echo "EOF" &&
+
+			echo "commit refs/heads/upstream" &&
+			echo "committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" &&
+			echo "data <<EOF" &&
+			echo "commit$i-reverse" &&
+			echo "EOF" &&
+			echo "M 100644 inline unrelated-file$i" &&
+			echo "data <<EOF" &&
+			echo "change$i" &&
+			cat content_rev &&
+			echo "EOF" || return 1
+		done &&
+		echo "done"
+	) | git fast-import --done &&
+
+	git repack -a -d &&
+	git checkout -f upstream &&
 	git checkout to-rebase &&
 	test_commit our-patch interesting-file
 '
-
 test_perf 'rebase on top of a lot of unrelated changes' '
 	git rebase --onto upstream HEAD^ &&
 	git rebase --onto base HEAD^
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] t/perf/p3400: speed up setup using fast-import
       [not found]       ` <b6f12614-ecc1-4d37-ac4c-070925054f28@gmail.com>
@ 2026-01-30 16:47         ` Johannes Sixt
  0 siblings, 0 replies; 14+ messages in thread
From: Johannes Sixt @ 2026-01-30 16:47 UTC (permalink / raw)
  To: Tian Yuchen; +Cc: git, Junio C Hamano

Am 30.01.26 um 17:39 schrieb Tian Yuchen:
> I will send V4 shortly.
In this case, please also undo the unnecessary removal of a blank line
at the end of the patch.

-- Hannes


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4] t/perf/p3400: speed up setup using fast-import
  2026-01-30 16:29   ` [PATCH v3] " Tian Yuchen
@ 2026-01-30 17:01     ` Tian Yuchen
  2026-01-30 17:10     ` [PATCH v3] " Junio C Hamano
  1 sibling, 0 replies; 14+ messages in thread
From: Tian Yuchen @ 2026-01-30 17:01 UTC (permalink / raw)
  To: git; +Cc: gitster, j6t, phillip.wood123

The setup phase in 't/perf/p3400-rebase.sh' generates 100 commits to
simulate a noisy history. It currently uses a shell loop that invokes
'git add', 'git commit', 'test_seq', and 'sort' in each iteration.
This incurs significant overhead due to repeated process spawning.

Optimize the setup by using 'git fast-import' to generate the commit
history. Additionally, pre-compute the forward and reversed file contents
to avoid repetitive execution of 'seq' and 'sort'.

To ensure the test measures rebase performance against a consistent
object layout (rather than the suboptimal pack/loose objects created
by the raw import), perform a full repack (`git repack -a -d`) at the
end of the setup.

This reduces the setup time significantly while maintaining the validity
of the subsequent performance tests.

Performance enhancement (Average value of 5 tests):
            Real        Rebase
  Before:  29.045s      13.34s
   After:  21.989s      12.84s

Measured on Lenovo Yoga 2020, Ubuntu 24.04.

Signed-off-by: Tian Yuchen <a3205153416@gmail.com>
---

Changes since v3:
- Refactored the fast-import generation to write to a temporary file 
  (`fast_import_stream`) instead of using a pipe. This allows for better 
  debugging if fast-import fails, as suggested by Johannes Sixt and 
  endorsed by Junio C Hamano.
- Switched from `return 1` to `exit 1` inside the subshell to correctly 
  propagate exit codes.
- Undid the unnecessary removal of a blank line.

 t/perf/p3400-rebase.sh | 53 ++++++++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/t/perf/p3400-rebase.sh b/t/perf/p3400-rebase.sh
index e6b0277729..425f484681 100755
--- a/t/perf/p3400-rebase.sh
+++ b/t/perf/p3400-rebase.sh
@@ -9,21 +9,44 @@ test_expect_success 'setup rebasing on top of a lot of changes' '
 	git checkout -f -B base &&
 	git checkout -B to-rebase &&
 	git checkout -B upstream &&
-	for i in $(test_seq 100)
-	do
-		# simulate huge diffs
-		echo change$i >unrelated-file$i &&
-		test_seq 1000 >>unrelated-file$i &&
-		git add unrelated-file$i &&
-		test_tick &&
-		git commit -m commit$i unrelated-file$i &&
-		echo change$i >unrelated-file$i &&
-		test_seq 1000 | sort -nr >>unrelated-file$i &&
-		git add unrelated-file$i &&
-		test_tick &&
-		git commit -m commit$i-reverse unrelated-file$i ||
-		return 1
-	done &&
+	test_seq 1000 >content_fwd &&
+	sort -nr content_fwd >content_rev &&
+	(
+		for i in $(test_seq 100)
+		do
+			test_tick &&
+			echo "commit refs/heads/upstream" &&
+			echo "committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" &&
+			echo "data <<EOF" &&
+			echo "commit$i" &&
+			echo "EOF" &&
+			
+			if test "$i" = 1; then
+				echo "from refs/heads/upstream^0"
+			fi &&
+
+			echo "M 100644 inline unrelated-file$i" &&
+			echo "data <<EOF" &&
+			echo "change$i" &&
+			cat content_fwd &&
+			echo "EOF" &&
+
+			echo "commit refs/heads/upstream" &&
+			echo "committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" &&
+			echo "data <<EOF" &&
+			echo "commit$i-reverse" &&
+			echo "EOF" &&
+			echo "M 100644 inline unrelated-file$i" &&
+			echo "data <<EOF" &&
+			echo "change$i" &&
+			cat content_rev &&
+			echo "EOF" || exit 1
+		done
+	) >fast_import_stream &&
+
+	git fast-import <fast_import_stream &&
+	git repack -a -d &&
+	git checkout -f upstream &&
 	git checkout to-rebase &&
 	test_commit our-patch interesting-file
 '
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v3] t/perf/p3400: speed up setup using fast-import
  2026-01-30 16:29   ` [PATCH v3] " Tian Yuchen
  2026-01-30 17:01     ` [PATCH v4] " Tian Yuchen
@ 2026-01-30 17:10     ` Junio C Hamano
  1 sibling, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2026-01-30 17:10 UTC (permalink / raw)
  To: Tian Yuchen; +Cc: git, j6t, phillip.wood123

Tian Yuchen <a3205153416@gmail.com> writes:

> Changes since v2:
> - Optimized `content_rev` generation by sorting `content_fwd` directly (Johannes Sixt).
> - Used `test_tick` and standard `$GIT_COMMITTER_*` variables for consistency (Phillip Wood).
> - Fixed typo "reversed" -> "reverse" to match original test (Phillip Wood).
> - Added "done" command and used `git fast-import --done` to prevent errors in the loop being ignored by the pipe (Phillip Wood).

Thanks.  Will replace.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-01-30 17:10 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-26 16:56 [PATCH V1][RFC] t/perf/p3400: speed up setup using fast-import Tian Yuchen
2026-01-26 17:06 ` Tian Yuchen
2026-01-28  4:33   ` Tian Yuchen
2026-01-28 15:25     ` Tian Yuchen
2026-01-28 16:07 ` [PATCH v2] " Tian Yuchen
2026-01-30  6:41   ` Johannes Sixt
2026-01-30  9:55     ` Johannes Sixt
2026-01-30 16:27     ` Junio C Hamano
     [not found]       ` <b6f12614-ecc1-4d37-ac4c-070925054f28@gmail.com>
2026-01-30 16:47         ` Johannes Sixt
2026-01-30 14:31   ` Phillip Wood
2026-01-30 15:40     ` Tian Yuchen
2026-01-30 16:29   ` [PATCH v3] " Tian Yuchen
2026-01-30 17:01     ` [PATCH v4] " Tian Yuchen
2026-01-30 17:10     ` [PATCH v3] " Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox