From patchwork Thu Jan 9 08:46:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 13932190 Received: from cloud.peff.net (cloud.peff.net [104.130.231.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B7062F2D for ; Thu, 9 Jan 2025 08:46:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=104.130.231.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736412413; cv=none; b=Btmerf6y0SfXOcg7Vcksq2UcwmRsyV+HC8D3i9Taio5s/XcdtDQacupry8mcuvt8HIivrhKfbIppl+z2j5R/Yhu/MlYEkUiw6yI/n6IDNJEqMtmw1ptAW534dLXgSme4QscGhMVAYJTMUlU2HVh1tuN75bSkZ1fmv2nh3iPvpNc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736412413; c=relaxed/simple; bh=A0tgNetaVLpeUdEDWB4z3h7ZaFLGeW55new43be59us=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=Hju1sG166xDrFORJElwL4tRsXWij5yEPFx4z1J5YyDJabNRMX7jh94k6rVBdyYcVXT8cXIGa91ZoH0Mo1f3+anNUk+QUkLzrJC//vyhAHpuaGO8klzDS5wzaO4pKcmOC49E9zFCkxnr3QrqScOMssRmHm941dt8Tm1u5MPBie9Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=peff.net; spf=pass smtp.mailfrom=peff.net; dkim=pass (2048-bit key) header.d=peff.net header.i=@peff.net header.b=Nlw+0bwI; arc=none smtp.client-ip=104.130.231.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=peff.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=peff.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=peff.net header.i=@peff.net header.b="Nlw+0bwI" Received: (qmail 25695 invoked by uid 109); 9 Jan 2025 08:46:50 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=peff.net; h=date:from:to:cc:subject:message-id:references:mime-version:content-type:content-transfer-encoding:in-reply-to; s=20240930; bh=A0tgNetaVLpeUdEDWB4z3h7ZaFLGeW55new43be59us=; b=Nlw+0bwIXvPxb7uoOuv0Xf2KOqdEUIOR6wMxOA2RMBO9XQxZCuHtgpPtF0h39uyELpe0y2Dz7nOMc7lonbSnTF7MAJXwqhT3OkEmxuN3LUzzeFkEtay6KGm662Vr7POAvXlxqdsNRiShbj90yvVYPcXFksTENmWJqwG4CcSjJ22TKmuajOAubUxxEyP6jwBl2H7Lzg7RyImRg3OyhXRGV00YsjOEFHg2k/7oHOyBxMaVXKceK2K9Kqt/CA6e4MXHO7UKmkcnGiAnFraabo9WMybhqVUTA3CXUpCvvW+qlhLjhG2hrkx24dICqR66FHVVT/APDxKSh698MlqZFuDj/g== Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with ESMTP; Thu, 09 Jan 2025 08:46:50 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 20340 invoked by uid 111); 9 Jan 2025 08:46:50 -0000 Received: from coredump.intra.peff.net (HELO coredump.intra.peff.net) (10.0.0.2) by peff.net (qpsmtpd/0.94) with (TLS_AES_256_GCM_SHA384 encrypted) ESMTPS; Thu, 09 Jan 2025 03:46:50 -0500 Authentication-Results: peff.net; auth=none Date: Thu, 9 Jan 2025 03:46:49 -0500 From: Jeff King To: Git List Cc: Junio C Hamano , Wink Saville Subject: [PATCH 07/14] tree-diff: drop path_appendnew() alloc optimization Message-ID: <20250109084649.GG2748836@coredump.intra.peff.net> References: <20250109082723.GA2748497@coredump.intra.peff.net> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20250109082723.GA2748497@coredump.intra.peff.net> When we're diffing trees, we create a list of combine_diff_path structs that represent changed paths. We allocate each struct and add it to the list with path_appendnew(), which we then feed to opt->pathchange(). That function tells us whether the path is of interest or not; if not, then we can throw away the struct we allocated. So there's an optimization to avoid extra allocations: instead of throwing away the new entry, we try to reuse it. If it was large enough to store the next path we care about, we can do so. And if not, we fall back to freeing and re-allocating a new struct. This comes from 72441af7c4 (tree-diff: rework diff_tree() to generate diffs for multiparent cases as well, 2014-04-07), where the goal was to have even the 2-parent diff code use the combine-diff infrastructure, but without taking a performance hit. The implementation causes some complexities in the interface (as we store the allocation length inside the "next" pointer), and prevents us from using the regular combine_diff_path_new() constructor. The complexity is mostly contained inside two functions, but it's worth re-evaluating how much it's helping. That commit claims it helps ~1% on generating two-parent diffs in linux.git. Here are the timings I get on the same command today ("old" is the current tip of master, and "new" has this patch applied): Benchmark 1: ./git.old log --raw --no-abbrev --no-renames v3.10..v3.11 Time (mean ± σ): 532.9 ms ± 5.8 ms [User: 472.7 ms, System: 59.6 ms] Range (min … max): 525.9 ms … 543.3 ms 10 runs Benchmark 2: ./git.new log --raw --no-abbrev --no-renames v3.10..v3.11 Time (mean ± σ): 538.3 ms ± 5.7 ms [User: 478.0 ms, System: 59.7 ms] Range (min … max): 528.5 ms … 545.3 ms 10 runs Summary ./git.old log --raw --no-abbrev --no-renames v3.10..v3.11 ran 1.01 ± 0.02 times faster than ./git.new log --raw --no-abbrev --no-renames v3.10..v3.11 So we do end up on average 1% faster, but with 2% of noise. I tried to focus more on diff performance by running the commit traversal separately, like: git rev-list v3.10..v3.11 >in and then timing just the diffs: Benchmark 1: ./git.old diff-tree --stdin -r