Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

It is surely a great calamity for a human being to have no obsessions. -- Robert Bly


devel / comp.lang.python / Re: sum() vs. loop

SubjectAuthor
* sum() vs. loopSteve Keller
+* Re: sum() vs. loopChristian Gollwitzer
|+* Re: sum() vs. loopSteve Keller
||`* Re: sum() vs. loopStefan Ram
|| `- Re: sum() vs. loopChris Angelico
|`- Re: sum() vs. loopOscar Benjamin
+- Re: sum() vs. loopChris Angelico
+* Re: sum() vs. loopDan Stromberg
|`- Re: sum() vs. loopChristian Gollwitzer
`- Re: sum() vs. loopGilmeh Serda

1
sum() vs. loop

<sju9fe$gh7$1@gioia.aioe.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15587&group=comp.lang.python#15587

  copy link   Newsgroups: comp.lang.python
Path: rocksolid2!i2pn.org!aioe.org!tnvp0JDfpyny2hgzXAmVKA.user.46.165.242.75.POSTED!not-for-mail
From: keller.s...@gmx.de (Steve Keller)
Newsgroups: comp.lang.python
Subject: sum() vs. loop
Date: Sun, 10 Oct 2021 10:49:50 +0200
Organization: Aioe.org NNTP Server
Message-ID: <sju9fe$gh7$1@gioia.aioe.org>
Injection-Info: gioia.aioe.org; logging-data="16935"; posting-host="tnvp0JDfpyny2hgzXAmVKA.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
X-Notice: Filtered by postfilter v. 0.9.2
 by: Steve Keller - Sun, 10 Oct 2021 08:49 UTC

I have found the sum() function to be much slower than to loop over the
operands myself:

def sum_products(seq1, seq2):
return sum([a * b for a, b in zip(seq1, seq2)])

def sum_products2(seq1, seq2):
sum = 0
for a, b in zip(seq1, seq2):
sum += a * b
return sum

In a program I generate about 14 million pairs of sequences of ints each
of length 15 which need to be summed. The first version with sum() needs
44 seconds while the second version runs in 37 seconds.

Can someone explain this difference?

Steve

Re: sum() vs. loop

<sjubom$l1g$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15588&group=comp.lang.python#15588

  copy link   Newsgroups: comp.lang.python
Path: rocksolid2!news.neodome.net!3.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: aurio...@gmx.de (Christian Gollwitzer)
Newsgroups: comp.lang.python
Subject: Re: sum() vs. loop
Date: Sun, 10 Oct 2021 11:28:54 +0200
Organization: A noiseless patient Spider
Lines: 27
Message-ID: <sjubom$l1g$1@dont-email.me>
References: <sju9fe$gh7$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sun, 10 Oct 2021 09:28:54 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="029a112b024b0d189e742081ee819e80";
logging-data="21552"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+w8siVmL3ynmT1WFn2DIoGhU/VjjnWumw="
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:78.0)
Gecko/20100101 Thunderbird/78.14.0
Cancel-Lock: sha1:598Fsh5b6jkseZxVA6yfA98U6V0=
In-Reply-To: <sju9fe$gh7$1@gioia.aioe.org>
 by: Christian Gollwitzer - Sun, 10 Oct 2021 09:28 UTC

Am 10.10.21 um 10:49 schrieb Steve Keller:
> I have found the sum() function to be much slower than to loop over the
> operands myself:
>
> def sum_products(seq1, seq2):
> return sum([a * b for a, b in zip(seq1, seq2)])
>
> def sum_products2(seq1, seq2):
> sum = 0
> for a, b in zip(seq1, seq2):
> sum += a * b
> return sum
>
> In a program I generate about 14 million pairs of sequences of ints each
> of length 15 which need to be summed. The first version with sum() needs
> 44 seconds while the second version runs in 37 seconds.

The first version constructs a list, sums it up and throws the list
away, while the second version only keeps the running sum in memory. How
about a generator expression instead, i.e.

sum((a * b for a, b in zip(seq1, seq2)))

(untested) ?

Christian

Re: sum() vs. loop

<sjusps$a57$1@gioia.aioe.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15590&group=comp.lang.python#15590

  copy link   Newsgroups: comp.lang.python
Path: rocksolid2!i2pn.org!aioe.org!tnvp0JDfpyny2hgzXAmVKA.user.46.165.242.75.POSTED!not-for-mail
From: keller.s...@gmx.de (Steve Keller)
Newsgroups: comp.lang.python
Subject: Re: sum() vs. loop
Date: Sun, 10 Oct 2021 16:19:40 +0200
Organization: Aioe.org NNTP Server
Message-ID: <sjusps$a57$1@gioia.aioe.org>
References: <sju9fe$gh7$1@gioia.aioe.org> <sjubom$l1g$1@dont-email.me>
Injection-Info: gioia.aioe.org; logging-data="10407"; posting-host="tnvp0JDfpyny2hgzXAmVKA.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
X-Notice: Filtered by postfilter v. 0.9.2
 by: Steve Keller - Sun, 10 Oct 2021 14:19 UTC

Christian Gollwitzer <auriocus@gmx.de> writes:

> > def sum_products(seq1, seq2):
> > return sum([a * b for a, b in zip(seq1, seq2)])
> > def sum_products2(seq1, seq2):
> > sum = 0
> > for a, b in zip(seq1, seq2):
> > sum += a * b
> > return sum
> > [...]
>
> The first version constructs a list, sums it up and throws the list
> away, while the second version only keeps the running sum in
> memory. How about a generator expression instead, i.e.
>
>
> sum((a * b for a, b in zip(seq1, seq2)))

Ah, of course. Much cleaner and I should have seen that myself.
Thanks.

BUT

> (untested) ?

I have tested it and with () instead of [] it's even slower:

explicit loop: 37s � .5s
sum([...]) 44s � .5s
sum((...)) 47.5s � .5s

Now completely surprised.

Steve

Re: sum() vs. loop

<sum-20211010174413@ram.dialup.fu-berlin.de>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15591&group=comp.lang.python#15591

  copy link   Newsgroups: comp.lang.python
Path: rocksolid2!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: ram...@zedat.fu-berlin.de (Stefan Ram)
Newsgroups: comp.lang.python
Subject: Re: sum() vs. loop
Date: 10 Oct 2021 16:48:01 GMT
Organization: Stefan Ram
Lines: 14
Expires: 1 Dec 2021 11:59:58 GMT
Message-ID: <sum-20211010174413@ram.dialup.fu-berlin.de>
References: <sju9fe$gh7$1@gioia.aioe.org> <sjubom$l1g$1@dont-email.me> <sjusps$a57$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Trace: news.uni-berlin.de glJd2WiuF9aZsez0KXZnRAEHmEqg6Q9ywgHwHsSTSeLFAG
X-Copyright: (C) Copyright 2021 Stefan Ram. All rights reserved.
Distribution through any means other than regular usenet
channels is forbidden. It is forbidden to publish this
article in the Web, to change URIs of this article into links,
and to transfer the body without this notice, but quotations
of parts in other Usenet posts are allowed.
X-No-Archive: Yes
Archive: no
X-No-Archive-Readme: "X-No-Archive" is set, because this prevents some
services to mirror the article in the web. But the article may
be kept on a Usenet archive server with only NNTP access.
X-No-Html: yes
Content-Language: en-US
Accept-Language: de-DE, en-US, it, fr-FR
 by: Stefan Ram - Sun, 10 Oct 2021 16:48 UTC

Steve Keller <keller.steve@gmx.de> writes:
>Now completely surprised.

I have observed that here the generator-based sum() call
is slower if both seq1 and seq2 have a length of 1000, but
faster if both seq1 and seq2 have 10000000 entries each
(with float entries).

However, in any case, the direct for-loop still is fastest.
Maybe, calling "next()" (actually, "PyIter_Next" in C) on
an iterator has some overhead compared to just evaluating
an expression in a loop.

Re: sum() vs. loop

<mailman.949.1633989474.4164.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15602&group=comp.lang.python#15602

  copy link   Newsgroups: comp.lang.python
Path: rocksolid2!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: ros...@gmail.com (Chris Angelico)
Newsgroups: comp.lang.python
Subject: Re: sum() vs. loop
Date: Tue, 12 Oct 2021 08:57:42 +1100
Lines: 30
Message-ID: <mailman.949.1633989474.4164.python-list@python.org>
References: <sju9fe$gh7$1@gioia.aioe.org>
<CAPTjJmoWq-k1Hb=JOW9PG3L6U3fVntQVDM+kGFDwUqpOj7LYCg@mail.gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
X-Trace: news.uni-berlin.de DYSYbiyyxnjoYtmyQ3huxQZB8D/SxC+FnbPUTiHGgUqg==
Return-Path: <rosuav@gmail.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=gmail.com header.i=@gmail.com header.b=NVzdlBT8;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.020
X-Spam-Evidence: '*H*': 0.96; '*S*': 0.00; 'def': 0.04; 'loop': 0.07;
'overhead': 0.09; 'memory': 0.15; 'chrisa': 0.16; 'directly,':
0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16;
'keller': 0.16; 'seconds.': 0.16; 'subject:() ': 0.16;
'subject:loop': 0.16; 'wrote:': 0.16; 'reduce': 0.19; 'tue,':
0.19; 'to:addr:python-list': 0.20; 'version': 0.23; 'function':
0.27; 'program': 0.31; 'to:name:python': 0.32; 'message-
id:@mail.gmail.com': 0.32; 'but': 0.32; 'someone': 0.34; 'header
:In-Reply-To:1': 0.34; 'received:google.com': 0.34; 'runs': 0.35;
'from:addr:gmail.com': 0.35; "it's": 0.37; 'received:209.85':
0.37; 'received:209': 0.39; 'use': 0.39; 'steve': 0.39; 'explain':
0.40; 'seconds': 0.40; 'try': 0.40; 'simply': 0.63; 'square':
0.69; '2021': 0.71; 'subject:. ': 0.73; 'pairs': 0.84;
'subject:sum': 0.84; 'million': 0.89
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
h=mime-version:references:in-reply-to:from:date:message-id:subject:to;
bh=rAc6IoXg0dMpAlMY7AqQpb/P00xYAzLh8axr9O/Fc5U=;
b=NVzdlBT80pRC1E2ycc8NnGHQcwMbGrKAJ6QF+HGupGM8tHCX9YMlrKxxwV4oJFSvRO
Gs2NbGQ6PqWtcQr1qKJ/2FJHHF5nbM6UUn5KQrhFFtl8hju2dPuaW9zuASr33ULzbA9S
XyWAXIpZxf2Gwbc9kMEIDMB2ugiQPXPrNg29TXAabc7f4t80CmaAjBrSpjxydT2Qb9HY
Xgg29g2Vl7HINe7AOr5NXygoC865X8mlMglcEigKnjomZ6rZcJTm3gpDqry+W2fZ17fr
hQobBK8RSxTsr9qnBQdLLdxCYizsTnrYt/QYICA/LAsc2iEwStmTBhNWsRiSBwpbPjRp
uM2A==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20210112;
h=x-gm-message-state:mime-version:references:in-reply-to:from:date
:message-id:subject:to;
bh=rAc6IoXg0dMpAlMY7AqQpb/P00xYAzLh8axr9O/Fc5U=;
b=EX9Xmnx3z7U5hDwcpkjfAySqXF5YB7z4BLW4PCPIFfgvFNX8ZFLSVtehhBAMW9yhPI
YlCIk9OfgTgXLQ+tWKrdA0cKyC/THubsJjmj1RqfR/Xo3aufg/UIKj9xFVmhTn7yvv41
3td1U0eyNmm8ZdLZ+DNpl5qO49TSSLHuJYx/fYJ/6WuUHy2kiQUnI0z8xvUIyWkDzRQh
qfP6WAeX6LPeBu5WM5398+33YtRonALrCZmknFbfS1QoVI8izZCWyFXl8Crf4kkhf0Nc
TATrKRkip8lk7/IUpVw/BVnNtoEIs83trVZKtxxnQ0YL4g/bAGtFrDxVA4E5/HAaT5Sx
zWxg==
X-Gm-Message-State: AOAM531toJzqkd0ImqgntSGzeCnZ7mlcXYqjJWzRAtis1WLGLGzxhe7M
yFXghJ9+5v82qytTcKY60tMiFYR1IYB9dD07zlwI1HJjYfZNYQ==
X-Google-Smtp-Source: ABdhPJzAxFIhGEBerF2AlGQz4BjSoIQUF7QkSSrSi9e2b4+NjntfGWCgEGhBO3IFMAsM22f9g6eQeWPYLFRIXlHljX8=
X-Received: by 2002:adf:bbc8:: with SMTP id z8mr28309521wrg.281.1633989472917;
Mon, 11 Oct 2021 14:57:52 -0700 (PDT)
In-Reply-To: <sju9fe$gh7$1@gioia.aioe.org>
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <CAPTjJmoWq-k1Hb=JOW9PG3L6U3fVntQVDM+kGFDwUqpOj7LYCg@mail.gmail.com>
X-Mailman-Original-References: <sju9fe$gh7$1@gioia.aioe.org>
 by: Chris Angelico - Mon, 11 Oct 2021 21:57 UTC

On Tue, Oct 12, 2021 at 8:55 AM Steve Keller <keller.steve@gmx.de> wrote:
>
> I have found the sum() function to be much slower than to loop over the
> operands myself:
>
> def sum_products(seq1, seq2):
> return sum([a * b for a, b in zip(seq1, seq2)])
>
> def sum_products2(seq1, seq2):
> sum = 0
> for a, b in zip(seq1, seq2):
> sum += a * b
> return sum
>
> In a program I generate about 14 million pairs of sequences of ints each
> of length 15 which need to be summed. The first version with sum() needs
> 44 seconds while the second version runs in 37 seconds.
>
> Can someone explain this difference?
>

When you use sum, you're constructing a list. Try removing the square brackets:

return sum(a * b for a, b in zip(seq1, seq2))

It's also possible that the genexp has more overhead than simply
iterating directly, but at very least, this will reduce the memory
consumption.

ChrisA

Re: sum() vs. loop

<mailman.950.1633989965.4164.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15603&group=comp.lang.python#15603

  copy link   Newsgroups: comp.lang.python
Path: rocksolid2!news.neodome.net!fu-berlin.de!uni-berlin.de!not-for-mail
From: ros...@gmail.com (Chris Angelico)
Newsgroups: comp.lang.python
Subject: Re: sum() vs. loop
Date: Tue, 12 Oct 2021 09:05:51 +1100
Lines: 24
Message-ID: <mailman.950.1633989965.4164.python-list@python.org>
References: <sju9fe$gh7$1@gioia.aioe.org> <sjubom$l1g$1@dont-email.me>
<sjusps$a57$1@gioia.aioe.org> <sum-20211010174413@ram.dialup.fu-berlin.de>
<CAPTjJmr9Pi=aaP2LJmgp+YCFcQZ8+jK_C50u=O6qg3WNMDtVXw@mail.gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
X-Trace: news.uni-berlin.de EmzBs9VxmtXePdzzyc5hHgjJ1kwKQMbTvRcx34MshLCg==
Return-Path: <rosuav@gmail.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=gmail.com header.i=@gmail.com header.b=J+FEzZjr;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.005
X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'loop': 0.07; 'ram': 0.07;
'effectively': 0.09; 'expression': 0.09; 'float': 0.09;
'overhead': 0.09; 'received:209.85.221.43': 0.09; 'received:mail-
wr1-f43.google.com': 0.09; 'writes:': 0.09; 'chrisa': 0.16;
'evaluating': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris
angelico': 0.16; 'keller': 0.16; 'picking': 0.16; 'subject:() ':
0.16; 'subject:loop': 0.16; 'whichever': 0.16; 'wrote:': 0.16;
'python': 0.16; 'code.': 0.17; 'tue,': 0.19; 'to:addr:python-
list': 0.20; 'code': 0.23; 'depends': 0.25; 'stefan': 0.26; 'it,':
0.29; 'putting': 0.31; 'to:name:python': 0.32; 'message-
id:@mail.gmail.com': 0.32; 'but': 0.32; 'requires': 0.34; 'header
:In-Reply-To:1': 0.34; 'received:google.com': 0.34;
'from:addr:gmail.com': 0.35; 'received:209.85': 0.37; 'way': 0.38;
'received:209': 0.39; 'list': 0.39; '(with': 0.39; 'steve': 0.39;
'still': 0.40; 'both': 0.40; 'try': 0.40; "there's": 0.61; 'here':
0.62; 'down': 0.64; 'entire': 0.67; '2021': 0.71; 'compared':
0.71; 'direct': 0.73; 'subject:. ': 0.73; 'callback': 0.84;
'subject:sum': 0.84; 'doing.': 0.91
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
h=mime-version:references:in-reply-to:from:date:message-id:subject:to;
bh=ZmMuCx7fNc8YTiVSU9gknpNw77JfF7Onj/XDQ6ajxPw=;
b=J+FEzZjruEwrHaGGFZSzLrJ9jo1O8kScxSuEy2bsTX9DUaTSWqDv11LYuEM47P1aVA
Nuj6RT22XMcUsXdJkdpEuoCB1BVSGJ9ZCV1l4Fdl4pHEG+XpEtNpocGU72xmcnzWrqrB
rcBH53vHLagaZWZ4ekDPQu7sHe6t8zVl/igOz5SwR4lSs+13Ikzt/RdPMYVDkZsI2KD0
ZsuR2+bRfBWsjsGdlDemSr5t1ZXpF0XQ9ey3cJavI4vL9RsMyH2msm7raJX/3ECtOGDq
IyS1cNwt4rXfmmitRrZPaVbPFRWaj5QHI+GQBdWdXrZhz3I3MI7x/CBbsEHnGWTnJSae
HNsA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20210112;
h=x-gm-message-state:mime-version:references:in-reply-to:from:date
:message-id:subject:to;
bh=ZmMuCx7fNc8YTiVSU9gknpNw77JfF7Onj/XDQ6ajxPw=;
b=Hjx6pQEUqP8KDWNFcjzAcpEwjIBMoUp2L1DDaXcf2a9h0g46mErjMcWtH+YVFLbA2Y
RHI+ugyu711Y/QApiU6jSgsjF1DDlxVZrdqWbdduzZ5lC2YY5aJUhDWeS2mPiEqgVj3R
0H7GE20XjM/k9h7ZpYD38FahXlDR38PKhXWcAo1lfbrFEx8mfedUSylcIsRrFyN1f7N4
XRk8kb3LFuH2vLBRcxs+dSTEoP5DyC+1wMW1NBOI/slsvr5SAu6/21nU8SC/t5WeSOxw
Bvk9bTQyHFX1I5lH6IwlrPvu9ytOWIZpYiJugY781M8ED9Ph/vvfrRTDT2e8ayWdmzll
QLwA==
X-Gm-Message-State: AOAM530iwjueBW/sMJLaTmXIL3rQ3LNPIbtY2+kG7ukHZGpvjCu+J5dv
/2Wsy8peYrVQ1UfFqlmFhzgyKBm3W6Ot604HWUK+MZA0RS0=
X-Google-Smtp-Source: ABdhPJwm/ssvF3dPHNB5kEPhfXJzpZzGyUS+tYq6sIaMngRV1IRc8QrqDt3B8lr7KvkGWS42oVR0k+1KeYetj5gQ/EA=
X-Received: by 2002:a7b:c08a:: with SMTP id r10mr1723463wmh.135.1633989963078;
Mon, 11 Oct 2021 15:06:03 -0700 (PDT)
In-Reply-To: <sum-20211010174413@ram.dialup.fu-berlin.de>
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <CAPTjJmr9Pi=aaP2LJmgp+YCFcQZ8+jK_C50u=O6qg3WNMDtVXw@mail.gmail.com>
X-Mailman-Original-References: <sju9fe$gh7$1@gioia.aioe.org>
<sjubom$l1g$1@dont-email.me>
<sjusps$a57$1@gioia.aioe.org> <sum-20211010174413@ram.dialup.fu-berlin.de>
 by: Chris Angelico - Mon, 11 Oct 2021 22:05 UTC

On Tue, Oct 12, 2021 at 9:02 AM Stefan Ram <ram@zedat.fu-berlin.de> wrote:
>
> Steve Keller <keller.steve@gmx.de> writes:
> >Now completely surprised.
>
> I have observed that here the generator-based sum() call
> is slower if both seq1 and seq2 have a length of 1000, but
> faster if both seq1 and seq2 have 10000000 entries each
> (with float entries).
>
> However, in any case, the direct for-loop still is fastest.
> Maybe, calling "next()" (actually, "PyIter_Next" in C) on
> an iterator has some overhead compared to just evaluating
> an expression in a loop.
>

There's overhead whichever way you do it, and ultimately, it depends
on what you're doing. The genexp is effectively a callback into Python
code. The list comp requires preconstruction of the entire list. The
plain for loop involves summing by picking up and putting down in
Python code rather than doing that in C. The only way to know which is
fastest is to try them all :)

ChrisA

Re: sum() vs. loop

<mailman.954.1634010109.4164.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15607&group=comp.lang.python#15607

  copy link   Newsgroups: comp.lang.python
Path: rocksolid2!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: drsali...@gmail.com (Dan Stromberg)
Newsgroups: comp.lang.python
Subject: Re: sum() vs. loop
Date: Mon, 11 Oct 2021 20:41:35 -0700
Lines: 27
Message-ID: <mailman.954.1634010109.4164.python-list@python.org>
References: <sju9fe$gh7$1@gioia.aioe.org>
<CAGGBd_rcaOOMFiS+EzyVtmStmdBUwS8TDwAHNZWFuzsEc2qeCA@mail.gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
X-Trace: news.uni-berlin.de Kf+cd+ps9KSfmmelyCTlvwJdbsEOweef1HpoygTDRA9Q==
Return-Path: <drsalists@gmail.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=gmail.com header.i=@gmail.com header.b=etZ0ppDD;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.008
X-Spam-Evidence: '*H*': 0.98; '*S*': 0.00; 'def': 0.04; 'loop': 0.07;
'cc:addr:python-list': 0.09; 'expression': 0.09; 'numpy': 0.09;
'speed,': 0.09; 'cc:name:python list': 0.16; 'cython,': 0.16;
'from:addr:drsalists': 0.16; 'from:name:dan stromberg': 0.16;
'idea.': 0.16; 'keller': 0.16; 'me.\xc2\xa0': 0.16; 'seconds.':
0.16; 'subject:() ': 0.16; 'subject:loop': 0.16; 'wrote:': 0.16;
'instead': 0.17; "can't": 0.17; 'cc:addr:python.org': 0.20;
'maybe': 0.22; 'version': 0.23; 'cc:2**0': 0.25; 'seems': 0.26;
'11,': 0.26; 'function': 0.27; 'program': 0.31; 'it.\xc2\xa0':
0.32; 'message-id:@mail.gmail.com': 0.32; 'but': 0.32; 'someone':
0.34; 'header:In-Reply-To:1': 0.34; 'received:google.com': 0.34;
'runs': 0.35; 'from:addr:gmail.com': 0.35; 'mon,': 0.36;
'received:209.85': 0.37; 'received:209': 0.39;
'received:209.85.222': 0.39; 'steve': 0.39; 'explain': 0.40;
'seconds': 0.40; 'try': 0.40; 'should': 0.40; 'me.': 0.62;
'great': 0.63; 'clarity': 0.69; 'generator': 0.69; '2021': 0.71;
'speed': 0.71; 'subject:. ': 0.73; 'pairs': 0.84; 'subject:sum':
0.84; 'million': 0.89
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
h=mime-version:references:in-reply-to:from:date:message-id:subject:to
:cc; bh=4wBBkxmoqb6xo26pFeXINxLUUXDkIxQHSxV2u04T8fI=;
b=etZ0ppDDDM1llk81XP+gKX1DeibpzqUOdYhmZoHeT7MSSKOM9CVdLabw1+3ecDJplg
7y3yhkoFJySp9g8VY3o/yKDVTL+4uEzTIPReOV36zMceaMC795tcI2koJOAM53cx7QnP
9dy7mmFtBc1gwH3xpoAvVUW342Ygjy8a8FGC1aAh+vkJs2QthVAT5YnAF1EXsom6P3af
gZcJtv9YVr1dEBBxACjdzc9lPm/LOnq9bGJ01B2n4VSNXyV2amSy/YT1QdkWi9h6mAf3
EEkYq8mfQbLqsZ0JPokR9hMeyHUCCnBaIPdPa7ODCEPXko0JTY7IsdCwVYOG+au2UB7l
JQZQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20210112;
h=x-gm-message-state:mime-version:references:in-reply-to:from:date
:message-id:subject:to:cc;
bh=4wBBkxmoqb6xo26pFeXINxLUUXDkIxQHSxV2u04T8fI=;
b=R2fHeX6M4BCZRjolFMfkhwYNDx3MTkvU+DARIHUm1pWrKIkEbdxQdic4QTEr43/cPE
8TpXz7ePb4lfmLW8rGmiCIlEqn7FY4zdnW4RS6xCLI7p2FtvohpSr+/wJZ1ek212S9oB
yh3i71T2bP1iQ0aLm4gChRti3FDQLTWPvR8B1eteBI6WuobM9YGjGTCppkL84zWqUCVq
ILg3uEeMyOdCXB/gFEuOvs1QbZNIPC3v2SH8Sabp1h3rGeo0dW0NncrEf4CFcJspG0zE
C7PH59Ht2MPi4KhQfyuQi/o1GnogO74f8SN8ovnAKHUmMmZ3BRulG+P1siF4Towx2FFs
Tp8g==
X-Gm-Message-State: AOAM532AnANXTXP1TyD1zM8HYP79DyV+YagoZcDtYBN1ZHyEuNhrgJkl
yAUj4ltfrhLw4uGIwSg02SM8es/ZJfiDGe8vEhSEhQD5
X-Google-Smtp-Source: ABdhPJwk2/GahvJsw3GYofBEyE1U5VKmmugrUDFSOuyvwD+f76qk36vvXcB5y+PYa+E9vhNi1zgZjuLzqyQbOcKh8lE=
X-Received: by 2002:a67:c205:: with SMTP id i5mr27970302vsj.19.1634010107141;
Mon, 11 Oct 2021 20:41:47 -0700 (PDT)
In-Reply-To: <sju9fe$gh7$1@gioia.aioe.org>
X-Content-Filtered-By: Mailman/MimeDel 2.1.34
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <CAGGBd_rcaOOMFiS+EzyVtmStmdBUwS8TDwAHNZWFuzsEc2qeCA@mail.gmail.com>
X-Mailman-Original-References: <sju9fe$gh7$1@gioia.aioe.org>
 by: Dan Stromberg - Tue, 12 Oct 2021 03:41 UTC

On Mon, Oct 11, 2021 at 2:54 PM Steve Keller <keller.steve@gmx.de> wrote:

> I have found the sum() function to be much slower than to loop over the
> operands myself:
>
> def sum_products(seq1, seq2):
> return sum([a * b for a, b in zip(seq1, seq2)])
>
> def sum_products2(seq1, seq2):
> sum = 0
> for a, b in zip(seq1, seq2):
> sum += a * b
> return sum
>
> In a program I generate about 14 million pairs of sequences of ints each
> of length 15 which need to be summed. The first version with sum() needs
> 44 seconds while the second version runs in 37 seconds.
>
> Can someone explain this difference?
>
I can't explain it. It might help to try a line-by-line profiler.

If you need speed, maybe try Cython, numpy and/or numba.

It seems like the generator expression should be the fastest to me. But
writing for speed instead of writing for clarity is usually not a great
idea.

Re: sum() vs. loop

<sk4llc$flh$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15616&group=comp.lang.python#15616

  copy link   Newsgroups: comp.lang.python
Path: rocksolid2!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: aurio...@gmx.de (Christian Gollwitzer)
Newsgroups: comp.lang.python
Subject: Re: sum() vs. loop
Date: Tue, 12 Oct 2021 20:52:21 +0200
Organization: A noiseless patient Spider
Lines: 29
Message-ID: <sk4llc$flh$1@dont-email.me>
References: <sju9fe$gh7$1@gioia.aioe.org>
<CAGGBd_rcaOOMFiS+EzyVtmStmdBUwS8TDwAHNZWFuzsEc2qeCA@mail.gmail.com>
<mailman.954.1634010109.4164.python-list@python.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 12 Oct 2021 18:54:36 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="22392020bf0bc535dea08e4671d0ee9f";
logging-data="16049"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/0sm4/9yPdjrdPkbzTb+KG17VWRhNMApU="
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:78.0)
Gecko/20100101 Thunderbird/78.14.0
Cancel-Lock: sha1:de99mLqrQxR6Dt+GKfXNjlRWayM=
In-Reply-To: <mailman.954.1634010109.4164.python-list@python.org>
 by: Christian Gollwitzer - Tue, 12 Oct 2021 18:52 UTC

Am 12.10.21 um 05:41 schrieb Dan Stromberg:
> On Mon, Oct 11, 2021 at 2:54 PM Steve Keller <keller.steve@gmx.de> wrote:
>
>> I have found the sum() function to be much slower than to loop over the
>> operands myself:
>>
>> def sum_products(seq1, seq2):
>> return sum([a * b for a, b in zip(seq1, seq2)])
>>
>> def sum_products2(seq1, seq2):
>> sum = 0
>> for a, b in zip(seq1, seq2):
>> sum += a * b
>> return sum

> It seems like the generator expression should be the fastest to me. But
> writing for speed instead of writing for clarity is usually not a great
> idea.
>

Maybe, unless this was just a test, it can be fastest AND clearest with

numpy.dot(seq1, seq2)

- in case that the sequence consists of floats and, in the best case, is
already stored in a numpy array. Then you cannot beat this with Python
code.

Christian

Re: sum() vs. loop

<mailman.965.1634143831.4164.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15623&group=comp.lang.python#15623

  copy link   Newsgroups: comp.lang.python
Path: rocksolid2!news.neodome.net!fu-berlin.de!uni-berlin.de!not-for-mail
From: oscar.j....@gmail.com (Oscar Benjamin)
Newsgroups: comp.lang.python
Subject: Re: sum() vs. loop
Date: Wed, 13 Oct 2021 17:49:55 +0100
Lines: 105
Message-ID: <mailman.965.1634143831.4164.python-list@python.org>
References: <sju9fe$gh7$1@gioia.aioe.org> <sjubom$l1g$1@dont-email.me>
<CAHVvXxR0_LdXnn2uhn4cwxD-NHxkAPX3UGRqL5r+EKka1Ggt9w@mail.gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Trace: news.uni-berlin.de tKVlqnJqpcbiT6lqEXvgtgSheZiLmNHsmoc7eFhcMg6w==
Return-Path: <oscar.j.benjamin@gmail.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=gmail.com header.i=@gmail.com header.b=YP9nCr+T;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.016
X-Spam-Evidence: '*H*': 0.97; '*S*': 0.00; 'def': 0.04; 'loop': 0.07;
'dev.': 0.09; 'expression': 0.09; 'int': 0.09; 'memory.': 0.09;
'overhead': 0.09; 'schrieb': 0.09; 'typically': 0.09; 'import':
0.15; 'memory': 0.15; 'afterwards': 0.16; 'all:': 0.16; 'builtin':
0.16; 'dominate': 0.16; 'each)': 0.16; 'elements:': 0.16;
'gollwitzer': 0.16; 'interpreter': 0.16; 'loops': 0.16;
'objects.': 0.16; 'operation.': 0.16; 'runtime': 0.16; 'seconds.':
0.16; 'subject:() ': 0.16; 'subject:loop': 0.16; 'yield': 0.16;
'wrote:': 0.16; 'python': 0.16; 'calls': 0.19; 'to:addr:python-
list': 0.20; 'creates': 0.22; 'i.e.': 0.22; 'skip:_ 10': 0.22;
'version': 0.23; 'list,': 0.24; 'function': 0.27; 'etc': 0.28;
'program': 0.31; 'think': 0.32; '109': 0.32; 'christian': 0.32;
'elements': 0.32; 'execution': 0.32; 'message-id:@mail.gmail.com':
0.32; '100': 0.33; 'header:In-Reply-To:1': 0.34;
'received:google.com': 0.34; 'running': 0.34; 'bar': 0.35; 'item':
0.35; 'runs': 0.35; 'from:addr:gmail.com': 0.35; 'built': 0.36;
'cases': 0.36; 'mon,': 0.36; 'those': 0.36; 'really': 0.37;
"it's": 0.37; 'received:209.85': 0.37; 'this.': 0.37;
'received:209': 0.39; 'least': 0.39; 'single': 0.39;
'received:209.85.208': 0.39; 'list': 0.39; 'methods': 0.39; 'on.':
0.39; 'steve': 0.39; 'exchange': 0.40; 'seconds': 0.40;
'something': 0.40; 'here.': 0.61; 'simply': 0.63; 'involve': 0.64;
'less': 0.65; 'types': 0.67; 'per': 0.68; 'cost': 0.69;
'generator': 0.69; 'instead,': 0.70; '2021': 0.71; 'compared':
0.71; 'speed': 0.71; 'longer': 0.71; 'subject:. ': 0.73;
'factors': 0.76; '10:49': 0.84; 'eliminates': 0.84; 'locals':
0.84; 'oscar': 0.84; 'pairs': 0.84; 'subject:sum': 0.84;
'million': 0.89; 'affect': 0.91; 'next.': 0.91
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
h=mime-version:references:in-reply-to:from:date:message-id:subject:to
:content-transfer-encoding;
bh=AwZ1QNlxtZwQFy0WdoNctR/q3na3VYhOfRt7VjBGQE0=;
b=YP9nCr+TlaSBAir5W8cDIHk/fGtAmZRr/kcvtmQqsmXrzYrewNZ7tyinETAWkxRuWa
82sMqggZRokEz8uMCfjRVTW9MUyr1tjr+ndzKJ1MmTvG/NvMqValFPKfDKtKhKDyvbXo
IBryiyFZWlNR7PrtZ8psqIhhMXuV1c9dLpjZHFmo8JEjE6EufYpkiYFaUd9DwhcwYWC/
/am1zfHHoKSuUJleobfTaouZUWhMJNuXHIbBU9KhOkSz1Rt83qRh/HLpFNvqq8OIE3iL
twYT7tIQ0bwPKxA8kMUYOS9zQl23Z5f2cQo2m6oYeV7oiWbQ3gKcnTDQeNLEIPXQU0AU
6FRg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20210112;
h=x-gm-message-state:mime-version:references:in-reply-to:from:date
:message-id:subject:to:content-transfer-encoding;
bh=AwZ1QNlxtZwQFy0WdoNctR/q3na3VYhOfRt7VjBGQE0=;
b=jAkKvp+vPQcmizFeFdQV7LCNvVfxE92X5RQ6coWRD0sjTbW+dvW6vwFqytsDyHZH8R
H1zn9D5hzUJpTyO1XG+fLjURtcVEx7rYUCqRaJnMy6yEu4cLgUhbuZKNUpDOJNcNdzH6
8uX+EeBu2wHwCUz699oqKRXw7WS2c2FoO9lg0AlWNXYm60F5KUGhdSyb0kX/kYLVjN3S
dgGRGJSkzBka7ZK46xVpE3NRwV96voAskHuVXzukJw2cCHFBqxScnRIjTUw9yF8iSiYl
Uiny4xCxlYCdG+4Y42lFPxV6a7SZMkRsOzZSZWNN56A2/0VhP+1zEEkvl+LkjSU8+gyA
+Gfw==
X-Gm-Message-State: AOAM531uD+FlEuxRYu5slt4++5AAtOC3237eYyES+MhZf2q/voZwOUrH
MO1iU//Y8s2DGH0kzwXyeTVUa11OR9H7kHbBH4f495QyjUg=
X-Google-Smtp-Source: ABdhPJz76uGXxhn3yX5CuL2It9M/7kQaSNu24gO+RSV2wbn5POtigBQtvHyVT8Cp8MjIHB2+etC3yd3gk2CcngDE5M0=
X-Received: by 2002:a17:906:6bce:: with SMTP id
t14mr375260ejs.546.1634143807478;
Wed, 13 Oct 2021 09:50:07 -0700 (PDT)
In-Reply-To: <sjubom$l1g$1@dont-email.me>
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <CAHVvXxR0_LdXnn2uhn4cwxD-NHxkAPX3UGRqL5r+EKka1Ggt9w@mail.gmail.com>
X-Mailman-Original-References: <sju9fe$gh7$1@gioia.aioe.org>
<sjubom$l1g$1@dont-email.me>
 by: Oscar Benjamin - Wed, 13 Oct 2021 16:49 UTC

On Mon, 11 Oct 2021 at 23:00, Christian Gollwitzer <auriocus@gmx.de> wrote:
>
> Am 10.10.21 um 10:49 schrieb Steve Keller:
> > I have found the sum() function to be much slower than to loop over the
> > operands myself:
> >
> > def sum_products(seq1, seq2):
> > return sum([a * b for a, b in zip(seq1, seq2)])
> >
> > def sum_products2(seq1, seq2):
> > sum = 0
> > for a, b in zip(seq1, seq2):
> > sum += a * b
> > return sum
> >
> > In a program I generate about 14 million pairs of sequences of ints each
> > of length 15 which need to be summed. The first version with sum() needs
> > 44 seconds while the second version runs in 37 seconds.
>
> The first version constructs a list, sums it up and throws the list
> away, while the second version only keeps the running sum in memory. How
> about a generator expression instead, i.e.
>
>
> sum((a * b for a, b in zip(seq1, seq2)))

What really matters in cases like this is interpreter overhead.
Typically a generator expression has slightly more overhead compared
to a list comprehension. You get a slightly slower per-item speed in
exchange for O(1) memory consumption.

A list comprehension like

result = sum([expr for foo in bar])

Translates internally to something like:

def _func():
data = []
for foo in bar:
data.append(foo)
return foo

_stuff = _func()
result = sum(_stuff)

Running this really does bring in the overhead of a function call
_func() because it needs to create a frame with locals and so on.
However it is only the cost of a single function call. Afterwards if
the elements in the list _stuff are built in types like int etc with
builtin __add__ methods then sum(_stuff) does not involve the
interpreter at all: it's a built-in function operating on a built-in
container of built-in objects.

With a generator expression like

result = sum(expr for foo in bar)

This translates internally to

def _genfunc():
for foo in bar:
yield foo

_gen = _genfunc()
result = sum(_gen)

Now the _genfunc() function call simply creates the generator and sets
up its frame which I think is more or less equivalent to the overhead
of the _func() function call. However the sum(_gen) line is no longer
a pure built-in operation. Internally each time sum calls
_gen.__next__() the execution frame for _genfunc() is reactivated so
that the interpreter can execute the bytecodes taking the frame from
one yield to the next. This is almost the overhead of a function call
for each item in bar although this is often unnoticeable in practice
and other factors can affect this.

The fastest version eliminates the interpreter altogether at least
when operating on pure built-in elements:

In [7]: nums1 = nums2 = list(range(10**5))

In [10]: %timeit sum([a*b for a, b in zip(nums1, nums2)])
9.83 ms ± 21.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [11]: %timeit sum((a*b for a, b in zip(nums1, nums2)))
10.3 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [12]: from operator import mul

In [13]: %timeit sum(map(mul, nums1, nums2))
7.25 ms ± 33 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Of course if the elements being multiplied and summed have pure-Python
__add__/__mul__ methods or the container has a pure Python
__iter__/__next__ then any of those methods will typically dominate
the runtime over any of the overheads considered here.

--
Oscar

Re: sum() vs. loop

<BuXcJ.858090$adE9.400138@fx14.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=15694&group=comp.lang.python#15694

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!usenet.goja.nl.eu.org!2.eu.feeder.erje.net!feeder.erje.net!newsfeed.xs4all.nl!newsfeed9.news.xs4all.nl!news-out.netnews.com!news.alt.net!fdc2.netnews.com!peer01.ams1!peer.ams1.xlned.com!news.xlned.com!peer02.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!fx14.ams4.POSTED!not-for-mail
From: gilmeh.s...@nothing.here.invalid (Gilmeh Serda)
Subject: Re: sum() vs. loop
Newsgroups: comp.lang.python
References: <sju9fe$gh7$1@gioia.aioe.org>
x-no-archive: yes
User-Agent: Pan/0.147 (Sweet Solitude; afc1447
refs/keep-around/afc1447e125596e4a9ed5ca96b0186ae28ba0bb0)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Lines: 14
Message-ID: <BuXcJ.858090$adE9.400138@fx14.ams4>
X-Complaints-To: abuse@easynews.com
Organization: Easynews - www.easynews.com
X-Complaints-Info: Please be sure to forward a copy of ALL headers otherwise we will be unable to process your complaint properly.
Date: Sat, 23 Oct 2021 17:19:29 GMT
X-Received-Bytes: 1271
 by: Gilmeh Serda - Sat, 23 Oct 2021 17:19 UTC

On Sun, 10 Oct 2021 10:49:50 +0200, Steve Keller wrote:

> 44 seconds while the second version runs in 37 seconds.
>
> Can someone explain this difference?

not me (memory shuffling maybe?), but could you use numpy in some manner?
it's pretty fast I hear, or redo that part in a compiled library if it's
often used, or maybe do it in PyPy

--
Gilmeh

Don't tell any big lies today. Small ones can be just as effective.

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor