Per the suggestion by Rewan in the comments, I pulled the January 2022 log of games from lichess and looked at all the 1+0 games that finished with "Normal" or "Time forfeit" results with both players making at least one move each.
The code I used is included below.
Notes:
Elapsed time is calculated as the sum of the starting clocks for each player minus the sum of the ending clocks for each player. Starting clocks (rather than a constant 120s) are used to handle the case when a player berserks.
I exclude cases where players gave their opponents more time (since this makes calculating elapsed time impossible from the PGN data given). At least, I try to; there are some cases that will be undetectable, such as giving time and the opponent using up all of that time prior to making their next more.
I do not use wall clock game creation time and game end time so as to avoid having the calculation artificially inflated with the extra non-game time introduced by the delay between game creation and game start and lag/ping latency.
Number of games: 27,398,824
Average time: 93.51 seconds
Median time: 104 seconds
Using just the games in which neither player berserks:
Number of games: 27,130,482
Average time: 93.77 seconds
Median time: 105 seconds
Histogram of durations in that second set (no berserks):

Note the blip at t=60s. This duration is over-represented due to the games that have exactly two moves with white timing out. These stem, I believe, from challenges in which the challenged player does not immediately respond, and the challenger (playing white) doesn't notice when the challenge is ultimately accepted.
Also note that the duration of the game is at least somewhat dependent on the strengths of the players. Here's a graph of the durations for games in which both players were about the same strength (Elo within 100 of each other) plotted against the players' average rating:

I'm guessing the sudden dip at the end is an artifact stemming from the lower game count there, although perhaps to reach that level, premoves really become much more necessary.
python3 code:
import glob
import os
import re
import statistics
def seconds(time_str):
"""convert h:mm:ss to total seconds"""
h, m, s = time_str.split(':')
return int(h) * 3600 + int(m) * 60 + int(s)
# function to verify each player's clock is monotone
# decreasing (if a player is given time by their
# opponent, then the calculation of total game time
# is not possible given only the PGN data supplied)
def non_increasing(l):
return all(x>=y for x, y in zip(l, l[1:]))
clock = re.compile(r'(?:\[%clk )(\d:\d\d:\d\d)')
ignore = 0
bullet = 0
time = 0
gameid = ""
alltimes = []
sanetimes = []
statfile = open('stats.txt','w')
statfile.write("%8s %3s %3s %5s %5s\n"
% ("GameID", "Dur", "nPly", "Wclk", "Bclk"))
for filename in glob.glob('*.pgn'):
print(filename)
with open(os.path.join(os.getcwd(), filename), 'r') as f:
line = f.readline()
while(line):
# "Site" is the second line of the each game, so it
# is a good place to serve up the reset
if(line.find('[Site ')>=0):
ignore = 0
timeout = 0
bullet = 0
s = line.split('"')
s = s[1].split('/')
gameid = s[-1]
if(line.find('[Variant')>=0):
ignore = 1
if(line.find('[TimeControl')>=0):
s = line.split('"')
if(s[1] == '60+0'):
bullet = 1
# ignore "Abandoned", "Unterminated", "Rules infraction"
# and any other nonstandard endings.
if(line.find('[Termination')>=0):
s = line.split('"')
if(s[1] == "Time forfeit"):
timeout = 1
elif(s[1] != "Normal"):
ignore = 1
if(line[0] == '1'):
if((bullet == 1) and (ignore == 0)):
times = clock.findall(line)
if(len(times) >= 2):
secs = [ seconds(item) for item in times ]
p1 = secs[::2]
p2 = secs[1::2]
# record the first clock value for each player.
# it should be 60, but if the player berserked
# then it will be 30. Whichever, we use this
# value to determine the elapsed time for that
# player's clock at the end.
s1 = p1[0]
s2 = p2[0]
if(s1<=60 and s2<=60 and non_increasing(p1)
and non_increasing(p2)):
t0 = secs[-1]
if(timeout == 0):
t1 = secs[-2]
dur = s1+s2 - (t0 + t1)
else:
dur = s1+s2 - t0
if(dur >= 0 and dur <=120):
statfile.write("%8s %3d %3d %5d %5d\n"
% (gameid, dur, len(secs), s1, s2))
alltimes.append(dur)
if(s1==60 and s2==60):
sanetimes.append(dur)
line = f.readline()
f.close()
statfile.close()
print("Number of games: ", len(alltimes))
print("Average time: %s seconds"
% ( statistics.mean(alltimes)))
print("Median time: %s seconds"
% ( statistics.median(alltimes)))
print("Number of non-berserked games: ", len(sanetimes))
print("Average time: %s seconds"
% ( statistics.mean(sanetimes)))
print("Median time: %s seconds"
% ( statistics.median(sanetimes)))