1BRC using ojAlgo
The One Billion Row Challenge (1BRC) is a fun exploration of how far modern Java can be pushed for aggregating one billion rows from a text file. Grab all your (virtual) threads, reach out to SIMD, optimize your GC, or pull any other trick, and create the fastest implementation for solving this task!
https://github.com/gunnarmorling/1brc
The One Billion Row Challenge just finished. I followed the development throughout the month with great interest, and I’m truly amazed by the results. A few days (or even weeks) into the challenge, when great progress had already been made, I would never have guessed that it would be possible to bring the execution time down to 1.5s – well done!
However impressed I am with the achievements I also find the results somewhat discouraging. The code of the fastest contributions look very different from what me and my colleagues write in our daily work. To write really fast (Java) code it seems you should:
- Use Unsafe, although you know you shouldn’t
- Not use any built-in, general purpose, classes. Everything needs to be custom built for precisely the problem at hand.
- Create as few Java objects as possible, and don’t use the heap – allocate whatever memory you need off-heap.
- Exploit every low level hack imaginable.
- Use GraalVM Native Image – not just any JVM.
That’s not a recipe for writing portable concise maintainable code. It would be a very bad idea to start writing code like this, in general. We make performance/design trade-offs all the time. It’s a natural part of the craft of writing code. What I find discouraging is how far from the clean code I’d like to see the fast code is.
What we can do is to perhaps go halfway. Whenever you’ve built something using the latest and greatest high level api:s, and got it working correctly, know that it can probably be 100 times faster. Maybe, you should try to make it 10 times faster. That can probably be done without entirely destroying the cleanliness of the code.
The baseline implementation of 1BRC is not artificially slow. I can very well imagine colleagues writing that code, and leaving it like that. Possibly they would make the stream parallel (bad idea in itself). It is possible to do much better than the baseline and still have clean code. The example below demonstrates one way to do that, using tools provided with ojAlgo. It is 10 times faster than the baseline, and is still clear concise code.
Example Code
OneBRC.javaimport java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.util.DoubleSummaryStatistics;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.ojalgo.OjAlgoUtils;
import org.ojalgo.concurrent.ProcessingService;
import org.ojalgo.netio.BasicLogger;
import org.ojalgo.netio.SegmentedFile;
import org.ojalgo.netio.SegmentedFile.Segment;
import org.ojalgo.netio.TextLineReader;
import org.ojalgo.type.CalendarDateUnit;
import org.ojalgo.type.Stopwatch;
import org.ojalgo.type.function.TwoStepMapper;
import org.ojalgo.type.keyvalue.EntryPair;
import org.ojalgo.type.keyvalue.EntryPair.KeyedPrimitive;
/**
* An example of how to use the SegmentedFile and ProcessingService classes to process a large file in
* parallel.
* <p>
* This is an implementation of the 1BRC using ojAlgo.
*
* @see https://github.com/gunnarmorling/1brc
* @see https://www.ojalgo.org/2024/02/1brc-using-ojalgo/
*/
public class OneBRC {
/**
* There will be one instance of this class per station (city). It is used to aggregate the temperature
* measurements for that station. Most 1BRC submissions have a similar class. The
* {@link DoubleSummaryStatistics} could have been used for this, but it has some overhead due to handling
* of infinities and NaNs not needed here.
*/
static final class Aggregator {
static double round(final double value) {
return Math.round(value * 10.0) / 10.0;
}
int count = 0;
double max = Double.NEGATIVE_INFINITY;
double min = Double.POSITIVE_INFINITY;
double sum = 0.0;
@Override
public String toString() {
return min + "/" + Aggregator.round(sum / count) + "/" + max;
}
void merge(final Aggregator other) {
if (other.min < min) {
min = other.min;
}
if (other.max > max) {
max = other.max;
}
sum += other.sum;
count += other.count;
}
void put(final double value) {
if (value < min) {
min = value;
}
if (value > max) {
max = value;
}
sum += value;
count++;
}
}
/**
* A file segment processor. This class implements much of the actual processing specific for this use
* case. Since it implements the TwoStepMapper interface there is standard functionality implemented in
* the ProcessingService class we can use. More precisely since it implements the
* TwoStepMapper.Combineable sub-interface it can be used with the
* ProcessingService.reduceCombineable(...) method, and we'll make use of that.
*/
static final class Processor implements TwoStepMapper.Combineable<SegmentedFile.Segment, SortedMap<String, Aggregator>, Processor> {
/**
* The standard Java Double.parseDouble(...) method is not used since it is too slow. This method only
* handles precisely the format used in the 1BRC data files, and is therefore much faster.
*/
private static double parseDouble(final String sequence, final int first, final int limit) {
int unscaled = 0;
boolean negative = false;
for (int i = first; i < limit; i++) {
char digit = sequence.charAt(i);
switch (digit) {
case '-':
negative = true;
break;
case '.':
break;
default:
unscaled = 10 * unscaled + digit - '0';
break;
}
}
if (negative) {
return -unscaled / 10D;
} else {
return unscaled / 10D;
}
}
/**
* The actual temperature measurements. The key is the station (city) name, and the value is the
* Aggregator instance for that station.
*/
private final Map<String, Aggregator> myAggregates = new HashMap<>(512);
/**
* The SegmentedFile instance this Processor is processing data from.
*/
private final SegmentedFile mySegmentedFile;
Processor(final SegmentedFile segmentedFile) {
super();
mySegmentedFile = segmentedFile;
}
/**
* Combine the internal state from another Processor instance into this one.
*/
@Override
public void combine(final Processor other) {
for (Map.Entry<String, Aggregator> entry : other.getEntries()) {
myAggregates.computeIfAbsent(entry.getKey(), k -> new Aggregator()).merge(entry.getValue());
}
}
/**
* Consume the data from one file segment – process all the lines in that file segment.
*/
@Override
public void consume(final Segment segment) {
try (TextLineReader reader = mySegmentedFile.newTextLineReader(segment)) {
reader.forEach(this::doOneLine);
} catch (IOException cause) {
throw new UncheckedIOException(cause);
}
}
/**
* Get the final sorted results
*/
@Override
public SortedMap<String, Aggregator> getResults() {
return new TreeMap<>(myAggregates);
}
/**
* Reset the internal state of this instance (to enable re-use).
*/
@Override
public void reset() {
myAggregates.clear();
}
/**
* Parse one line of data, and add the temperature measurement to the correct station aggregator.
*/
private void doOneLine(final String line) {
int split = line.indexOf(";");
String station = line.substring(0, split);
double temperature = Processor.parseDouble(line, split + 1, line.length());
myAggregates.computeIfAbsent(station, key -> new Aggregator()).put(temperature);
}
Set<Entry<String, OneBRC.Aggregator>> getEntries() {
return myAggregates.entrySet();
}
}
static final File FILE = new File("/Users/apete/Developer/data/1BRC/measurements.txt");
/**
* A ProcessingService is a thin utility wrapper around an ExecutorService. It simplifies some processing.
* In particular it makes use of a TwoStepMapper to process a collection of work items. It's somewhat like
* a Collector (used with streams) but all in one interface.
*/
static final ProcessingService PROCSERV = ProcessingService.INSTANCE;
public static void main(final String[] args) throws IOException {
BasicLogger.debug();
BasicLogger.debug(OneBRC.class);
BasicLogger.debug(OjAlgoUtils.getTitle());
BasicLogger.debug(OjAlgoUtils.getDate());
BasicLogger.debug();
SortedMap<String, OneBRC.Aggregator> results = null;
/*
* First we'll execute a re-implementation of the 1BRC baseline. The code is more or less the same as
* the original, but it's using the Aggregator built for the ojAlgo version of the 1BRC as well as
* KeyedPrimitive and EntryPair that are part of the ojAlgo library.
*/
Stopwatch stopwatch = new Stopwatch();
Collector<KeyedPrimitive<String>, ?, Map<String, OneBRC.Aggregator>> collector = Collectors.groupingBy(KeyedPrimitive::getKey,
Collector.of(Aggregator::new, (aggr, pair) -> {
aggr.put(pair.doubleValue());
}, (aggr1, aggr2) -> {
aggr1.merge(aggr2);
return aggr1;
}));
results = null;
BasicLogger.debug();
stopwatch.reset();
results = new TreeMap<>(Files.lines(FILE.toPath()).map(OneBRC::parseLine).collect(collector));
BasicLogger.debug(results);
BasicLogger.debug("Baseline: {}", stopwatch.stop(CalendarDateUnit.SECOND));
/*
* Baseline parallelised – exactly the same code just using parallel streams instead.
*/
results = null;
BasicLogger.debug();
stopwatch.reset();
results = new TreeMap<>(Files.lines(FILE.toPath()).parallel().map(OneBRC::parseLine).collect(collector));
BasicLogger.debug(results);
BasicLogger.debug("Parallelised: {}", stopwatch.stop(CalendarDateUnit.SECOND));
/*
* Now the ojAlgo way.
*/
results = null;
BasicLogger.debug();
stopwatch.reset();
try (SegmentedFile segmented = SegmentedFile.of(FILE)) {
results = PROCSERV.reduceCombineable(segmented.segments(), () -> new Processor(segmented));
BasicLogger.debug(results);
}
/*
* The most important difference is that the ojAlgo version uses SegmentedFile and a ProcessingService
* rather than Java's standard Files.lines(...) and parallel streams. The ojAlgo version is also
* parallelised, but it's done in a more controlled way. The ojAlgo version is also more memory
* efficient and more scalable.
*/
BasicLogger.debug("ojAlgo: {}", stopwatch.stop(CalendarDateUnit.SECOND));
}
/**
* Used to re-implement the 1BRC baseline.
*/
static KeyedPrimitive<String> parseLine(final String line) {
String[] parts = line.split(";");
return EntryPair.of(parts[0], Double.parseDouble(parts[1]));
}
}
Console Output
Running the above program gives the following output.
class OneBRC
ojAlgo
2024-02-04
{Abha=-31.3/18.0/67.4, Abidjan=-26.9/26.0/75.5, Abéché=-23.4/29.4/81.5, Accra=-24.7/26.4/78.4, Addis Ababa=-30.9/16.0/65.5, Adelaide=-33.8/17.3/65.0, Aden=-22.6/29.1/78.1, Ahvaz=-22.1/25.4/75.1, Albuquerque=-39.2/14.0/61.5, Alexandra=-40.0/11.0/60.9, Alexandria=-27.9/20.0/69.2, Algiers=-33.0/18.2/70.9, Alice Springs=-27.1/21.0/70.5, Almaty=-37.9/10.0/58.3, Amsterdam=-38.6/10.2/60.7, Anadyr=-60.7/-6.9/42.8, Anchorage=-45.8/2.8/50.6, Andorra la Vella=-40.0/9.8/57.4, Ankara=-36.8/12.0/62.5, Antananarivo=-30.4/17.9/68.4, Antsiranana=-27.0/25.2/75.8, Arkhangelsk=-52.3/1.3/50.5, Ashgabat=-35.3/17.1/67.8, Asmara=-35.3/15.6/64.2, Assab=-27.5/30.5/81.6, Astana=-47.5/3.5/53.3, Athens=-32.2/19.2/67.5, Atlanta=-33.2/17.0/66.1, Auckland=-37.4/15.2/63.9, Austin=-29.0/20.7/73.7, Baghdad=-30.8/22.8/70.6, Baguio=-32.7/19.5/72.4, Baku=-34.7/15.1/66.2, Baltimore=-38.2/13.1/61.2, Bamako=-23.2/27.8/76.9, Bangkok=-20.5/28.6/80.0, Bangui=-25.4/26.0/73.9, Banjul=-27.3/26.0/74.0, Barcelona=-31.5/18.2/74.2, Bata=-27.9/25.1/75.2, Batumi=-34.6/14.0/63.1, Beijing=-37.9/12.9/60.9, Beirut=-30.6/20.9/71.0, Belgrade=-42.1/12.5/63.0, Belize City=-26.1/26.7/75.4, Benghazi=-29.1/19.9/68.6, Bergen=-45.9/7.7/60.4, Berlin=-42.5/10.3/59.9, Bilbao=-42.8/14.7/66.7, Birao=-21.2/26.5/75.6, Bishkek=-38.1/11.3/61.4, Bissau=-19.7/27.0/76.6, Blantyre=-27.1/22.2/69.5, Bloemfontein=-36.3/15.6/67.2, Boise=-39.6/11.4/61.0, Bordeaux=-34.6/14.2/63.2, Bosaso=-16.4/30.0/78.1, Boston=-43.9/10.9/59.0, Bouaké=-27.5/26.0/77.2, Bratislava=-40.8/10.5/60.4, Brazzaville=-24.2/25.0/76.0, Bridgetown=-26.8/27.0/75.3, Brisbane=-30.0/21.4/71.7, Brussels=-41.9/10.5/63.0, Bucharest=-37.5/10.8/59.1, Budapest=-40.2/11.3/59.1, Bujumbura=-25.1/23.8/74.6, Bulawayo=-39.0/18.9/69.2, Burnie=-38.6/13.1/60.2, Busan=-34.8/15.0/66.2, Cabo San Lucas=-23.6/23.9/72.5, Cairns=-32.9/25.0/76.5, Cairo=-31.5/21.4/69.4, Calgary=-44.4/4.4/56.4, Canberra=-34.6/13.1/68.1, Cape Town=-34.7/16.2/70.1, Changsha=-31.8/17.4/68.4, Charlotte=-32.1/16.1/65.9, Chiang Mai=-24.5/25.8/74.8, Chicago=-40.9/9.8/60.4, Chihuahua=-30.5/18.6/66.3, Chittagong=-22.4/25.9/75.0, Chișinău=-41.1/10.2/61.7, Chongqing=-32.1/18.6/74.2, Christchurch=-38.6/12.2/63.0, City of San Marino=-37.1/11.8/61.8, Colombo=-23.2/27.4/77.1, Columbus=-37.3/11.7/64.9, Conakry=-21.9/26.4/76.5, Copenhagen=-39.5/9.1/58.3, Cotonou=-22.8/27.2/78.0, Cracow=-44.4/9.3/57.6, Da Lat=-29.4/17.9/67.8, Da Nang=-24.3/25.8/76.5, Dakar=-33.6/24.0/74.7, Dallas=-36.0/19.0/68.2, Damascus=-33.0/17.0/68.7, Dampier=-30.0/26.4/74.0, Dar es Salaam=-29.5/25.8/72.5, Darwin=-21.5/27.6/77.2, Denpasar=-22.6/23.7/73.0, Denver=-43.9/10.4/58.2, Detroit=-39.9/10.0/59.9, Dhaka=-21.8/25.9/73.5, Dikson=-65.9/-11.1/37.2, Dili=-20.8/26.6/75.4, Djibouti=-20.9/29.9/84.0, Dodoma=-27.8/22.7/73.1, Dolisie=-23.0/24.0/77.1, Douala=-19.4/26.7/76.4, Dubai=-22.4/26.9/76.4, Dublin=-40.9/9.8/66.4, Dunedin=-41.6/11.1/58.8, Durban=-36.4/20.6/69.2, Dushanbe=-34.7/14.7/63.6, Edinburgh=-37.6/9.3/60.0, Edmonton=-45.0/4.2/53.7, El Paso=-33.3/18.1/73.6, Entebbe=-31.3/21.0/71.6, Erbil=-32.3/19.5/66.1, Erzurum=-49.7/5.1/53.4, Fairbanks=-50.5/-2.3/46.3, Fianarantsoa=-32.6/17.9/71.9, Flores, Petén=-21.3/26.4/76.2, Frankfurt=-38.1/10.6/60.9, Fresno=-29.5/17.9/68.7, Fukuoka=-33.1/17.0/68.2, Gaborone=-26.7/21.0/69.7, Gabès=-29.3/19.5/74.6, Gagnoa=-25.4/26.0/77.5, Gangtok=-34.3/15.2/64.3, Garissa=-20.6/29.3/78.3, Garoua=-20.7/28.3/78.1, George Town=-22.5/27.9/84.2, Ghanzi=-27.8/21.4/72.2, Gjoa Haven=-64.4/-14.4/32.8, Guadalajara=-29.6/20.9/72.6, Guangzhou=-25.7/22.4/70.3, Guatemala City=-29.9/20.4/71.9, Halifax=-41.7/7.5/57.0, Hamburg=-41.9/9.7/58.9, Hamilton=-37.5/13.8/63.7, Hanga Roa=-27.6/20.5/70.8, Hanoi=-29.5/23.6/72.6, Harare=-28.8/18.4/65.8, Harbin=-43.4/5.0/54.9, Hargeisa=-28.6/21.7/71.8, Hat Yai=-24.9/27.0/77.9, Havana=-23.7/25.2/77.5, Helsinki=-47.9/5.9/59.5, Heraklion=-31.1/18.9/70.9, Hiroshima=-30.5/16.3/65.2, Ho Chi Minh City=-24.3/27.4/77.9, Hobart=-35.6/12.7/63.1, Hong Kong=-23.3/23.3/76.9, Honiara=-28.3/26.5/84.3, Honolulu=-23.9/25.4/77.2, Houston=-30.3/20.8/73.3, Ifrane=-36.9/11.4/62.7, Indianapolis=-38.0/11.8/68.8, Iqaluit=-58.7/-9.3/42.5, Irkutsk=-47.7/1.0/57.0, Istanbul=-37.6/13.9/62.9, Jacksonville=-35.5/20.3/67.3, Jakarta=-26.1/26.7/75.5, Jayapura=-22.7/27.0/73.8, Jerusalem=-29.2/18.3/70.4, Johannesburg=-34.4/15.5/63.0, Jos=-27.0/22.8/74.0, Juba=-20.7/27.8/76.7, Kabul=-38.8/12.1/58.7, Kampala=-28.7/20.0/68.9, Kandi=-26.0/27.7/77.4, Kankan=-23.3/26.5/77.6, Kano=-21.9/26.4/74.1, Kansas City=-40.7/12.5/65.2, Karachi=-23.1/26.0/72.6, Karonga=-24.2/24.4/72.9, Kathmandu=-36.0/18.3/69.0, Khartoum=-21.8/29.9/80.3, Kingston=-19.2/27.4/78.8, Kinshasa=-23.8/25.3/75.6, Kolkata=-24.4/26.7/78.5, Kuala Lumpur=-22.0/27.3/77.7, Kumasi=-25.2/26.0/73.4, Kunming=-34.8/15.7/67.0, Kuopio=-50.0/3.4/49.3, Kuwait City=-26.8/25.7/77.8, Kyiv=-38.9/8.4/56.9, Kyoto=-36.9/15.8/66.7, La Ceiba=-23.5/26.2/78.0, La Paz=-23.3/23.7/75.4, Lagos=-22.8/26.8/77.0, Lahore=-28.1/24.3/71.7, Lake Havasu City=-28.5/23.7/72.4, Lake Tekapo=-39.0/8.7/65.6, Las Palmas de Gran Canaria=-28.8/21.2/73.0, Las Vegas=-29.9/20.3/69.9, Launceston=-36.8/13.1/62.7, Lhasa=-43.6/7.6/57.9, Libreville=-23.4/25.9/74.4, Lisbon=-35.5/17.5/65.8, Livingstone=-26.0/21.8/70.5, Ljubljana=-38.9/10.9/62.4, Lodwar=-18.9/29.3/78.3, Lomé=-22.2/26.9/76.0, London=-43.1/11.3/61.6, Los Angeles=-29.2/18.6/74.2, Louisville=-35.6/13.9/64.0, Luanda=-22.5/25.8/73.0, Lubumbashi=-28.8/20.8/70.0, Lusaka=-28.0/19.9/67.3, Luxembourg City=-43.2/9.3/62.4, Lviv=-41.3/7.8/55.1, Lyon=-37.3/12.5/59.9, Madrid=-34.2/15.0/63.1, Mahajanga=-29.1/26.3/75.4, Makassar=-27.0/26.7/75.2, Makurdi=-25.1/26.0/72.7, Malabo=-21.0/26.3/78.0, Malé=-22.6/28.0/78.5, Managua=-24.6/27.3/78.5, Manama=-21.0/26.5/79.4, Mandalay=-24.3/28.0/75.9, Mango=-20.6/28.1/75.6, Manila=-26.1/28.4/77.5, Maputo=-25.1/22.8/70.8, Marrakesh=-31.5/19.6/69.2, Marseille=-33.7/15.8/66.1, Maun=-28.9/22.4/69.8, Medan=-23.0/26.5/79.2, Mek'ele=-28.4/22.7/71.5, Melbourne=-34.1/15.1/65.7, Memphis=-38.9/17.2/68.9, Mexicali=-26.3/23.1/72.1, Mexico City=-29.3/17.5/68.0, Miami=-22.4/24.9/78.8, Milan=-36.0/13.0/68.5, Milwaukee=-40.3/8.9/60.8, Minneapolis=-40.9/7.8/58.0, Minsk=-42.2/6.7/55.8, Mogadishu=-21.7/27.1/79.5, Mombasa=-22.5/26.3/76.5, Monaco=-35.1/16.4/63.7, Moncton=-40.7/6.1/54.4, Monterrey=-31.2/22.3/70.8, Montreal=-43.8/6.8/57.3, Moscow=-44.5/5.8/52.8, Mumbai=-23.4/27.1/78.5, Murmansk=-49.3/0.6/51.3, Muscat=-20.1/28.0/77.8, Mzuzu=-33.3/17.7/66.7, N'Djamena=-19.6/28.3/79.4, Naha=-24.2/23.1/75.7, Nairobi=-32.9/17.8/66.1, Nakhon Ratchasima=-20.4/27.3/81.4, Napier=-36.2/14.6/64.8, Napoli=-35.2/15.9/65.3, Nashville=-35.5/15.4/63.4, Nassau=-25.0/24.6/76.8, Ndola=-31.1/20.3/73.0, New Delhi=-25.1/25.0/73.2, New Orleans=-26.8/20.7/72.9, New York City=-35.7/12.9/66.4, Ngaoundéré=-28.7/22.0/68.7, Niamey=-21.9/29.3/79.8, Nicosia=-29.2/19.7/69.8, Niigata=-36.6/13.9/63.8, Nouadhibou=-27.7/21.3/69.7, Nouakchott=-29.0/25.7/76.4, Novosibirsk=-45.8/1.7/48.5, Nuuk=-55.4/-1.4/51.2, Odesa=-40.9/10.7/61.1, Odienné=-24.1/26.0/74.3, Oklahoma City=-30.8/15.9/67.0, Omaha=-37.8/10.6/60.3, Oranjestad=-21.0/28.1/80.5, Oslo=-40.9/5.7/54.4, Ottawa=-40.0/6.6/55.3, Ouagadougou=-23.4/28.3/79.2, Ouahigouya=-21.8/28.6/78.8, Ouarzazate=-31.4/18.9/67.1, Oulu=-52.5/2.7/52.1, Palembang=-19.9/27.3/76.9, Palermo=-31.4/18.5/72.2, Palm Springs=-27.0/24.5/73.3, Palmerston North=-37.4/13.2/66.5, Panama City=-26.9/28.0/76.0, Parakou=-21.2/26.8/76.0, Paris=-35.9/12.3/64.8, Perth=-32.0/18.7/64.9, Petropavlovsk-Kamchatsky=-48.0/1.9/52.1, Philadelphia=-37.0/13.2/65.1, Phnom Penh=-19.9/28.3/77.7, Phoenix=-25.9/23.9/70.3, Pittsburgh=-42.5/10.8/58.8, Podgorica=-32.6/15.3/64.7, Pointe-Noire=-23.4/26.1/82.4, Pontianak=-21.7/27.7/86.7, Port Moresby=-22.3/26.9/78.2, Port Sudan=-21.1/28.4/76.4, Port Vila=-23.0/24.3/74.9, Port-Gentil=-21.5/26.0/78.7, Portland (OR)=-35.3/12.4/63.5, Porto=-31.5/15.7/62.1, Prague=-47.7/8.4/58.0, Praia=-26.3/24.4/74.2, Pretoria=-36.2/18.2/66.2, Pyongyang=-39.2/10.8/63.3, Rabat=-32.0/17.2/64.7, Rangpur=-27.6/24.4/70.1, Reggane=-19.9/28.3/77.9, Reykjavík=-46.9/4.3/52.9, Riga=-44.9/6.2/56.0, Riyadh=-23.4/26.0/78.7, Rome=-34.9/15.2/64.0, Roseau=-23.0/26.2/76.7, Rostov-on-Don=-45.2/9.9/58.9, Sacramento=-34.7/16.3/68.6, Saint Petersburg=-42.6/5.8/53.8, Saint-Pierre=-44.8/5.7/56.7, Salt Lake City=-36.9/11.6/60.0, San Antonio=-27.8/20.8/69.1, San Diego=-33.1/17.8/67.1, San Francisco=-40.8/14.6/63.6, San Jose=-30.7/16.4/67.7, San José=-26.5/22.6/75.2, San Juan=-23.6/27.2/78.0, San Salvador=-32.6/23.1/74.4, Sana'a=-28.7/20.0/69.2, Santo Domingo=-23.6/25.9/76.7, Sapporo=-42.8/8.9/60.3, Sarajevo=-39.5/10.1/60.5, Saskatoon=-46.8/3.3/52.2, Seattle=-40.8/11.3/61.4, Seoul=-35.3/12.5/61.7, Seville=-31.2/19.2/70.4, Shanghai=-32.9/16.7/67.6, Singapore=-22.7/27.0/77.4, Skopje=-37.3/12.4/60.6, Sochi=-31.5/14.2/65.1, Sofia=-45.0/10.6/61.8, Sokoto=-20.1/28.0/76.9, Split=-35.7/16.1/66.0, St. John's=-45.4/5.0/50.8, St. Louis=-37.6/13.9/66.7, Stockholm=-47.1/6.6/55.5, Surabaya=-28.4/27.1/76.0, Suva=-29.1/25.6/74.1, Suwałki=-43.6/7.2/55.0, Sydney=-31.3/17.7/69.2, Ségou=-23.4/28.0/74.4, Tabora=-28.2/23.0/71.5, Tabriz=-38.1/12.6/68.4, Taipei=-28.8/23.0/70.1, Tallinn=-45.6/6.4/52.7, Tamale=-20.3/27.9/76.5, Tamanrasset=-27.1/21.7/69.5, Tampa=-29.8/22.9/71.5, Tashkent=-34.4/14.8/63.9, Tauranga=-34.9/14.8/64.5, Tbilisi=-39.1/12.9/61.9, Tegucigalpa=-34.3/21.7/69.5, Tehran=-32.2/17.0/71.3, Tel Aviv=-29.8/20.0/69.4, Thessaloniki=-33.2/16.0/68.5, Thiès=-27.0/24.0/76.8, Tijuana=-36.6/17.8/66.7, Timbuktu=-20.4/28.0/80.1, Tirana=-36.3/15.2/64.3, Toamasina=-25.5/23.4/76.7, Tokyo=-40.6/15.4/66.8, Toliara=-25.2/24.1/73.2, Toluca=-42.8/12.4/62.4, Toronto=-44.8/9.4/58.1, Tripoli=-34.6/20.0/75.1, Tromsø=-45.7/2.9/53.5, Tucson=-30.1/20.9/70.5, Tunis=-31.5/18.4/68.0, Ulaanbaatar=-47.8/-0.4/49.7, Upington=-30.1/20.4/73.3, Vaduz=-38.4/10.1/58.4, Valencia=-29.5/18.3/73.5, Valletta=-31.6/18.8/70.9, Vancouver=-38.0/10.4/62.7, Veracruz=-26.8/25.4/78.0, Vienna=-39.7/10.4/62.2, Vientiane=-26.9/25.9/78.2, Villahermosa=-22.0/27.1/74.1, Vilnius=-44.1/6.0/55.0, Virginia Beach=-34.0/15.8/67.0, Vladivostok=-45.1/4.9/56.4, Warsaw=-40.5/8.5/56.3, Washington, D.C.=-33.1/14.6/64.4, Wau=-24.6/27.8/77.5, Wellington=-34.1/12.9/65.5, Whitehorse=-52.5/-0.1/47.5, Wichita=-39.0/13.9/64.6, Willemstad=-22.2/28.0/77.7, Winnipeg=-47.1/3.0/50.6, Wrocław=-42.4/9.6/59.3, Xi'an=-35.8/14.1/62.0, Yakutsk=-59.9/-8.8/41.9, Yangon=-27.6/27.5/76.1, Yaoundé=-28.6/23.8/72.9, Yellowknife=-55.7/-4.3/49.2, Yerevan=-37.2/12.4/67.7, Yinchuan=-39.4/9.0/62.1, Zagreb=-38.9/10.7/62.2, Zanzibar City=-24.6/26.0/78.6, Zürich=-44.3/9.3/59.4, Ürümqi=-43.3/7.4/59.1, İzmir=-30.7/17.9/68.5}
Baseline: 165.436960959s
{Abha=-31.3/18.0/67.4, Abidjan=-26.9/26.0/75.5, Abéché=-23.4/29.4/81.5, Accra=-24.7/26.4/78.4, Addis Ababa=-30.9/16.0/65.5, Adelaide=-33.8/17.3/65.0, Aden=-22.6/29.1/78.1, Ahvaz=-22.1/25.4/75.1, Albuquerque=-39.2/14.0/61.5, Alexandra=-40.0/11.0/60.9, Alexandria=-27.9/20.0/69.2, Algiers=-33.0/18.2/70.9, Alice Springs=-27.1/21.0/70.5, Almaty=-37.9/10.0/58.3, Amsterdam=-38.6/10.2/60.7, Anadyr=-60.7/-6.9/42.8, Anchorage=-45.8/2.8/50.6, Andorra la Vella=-40.0/9.8/57.4, Ankara=-36.8/12.0/62.5, Antananarivo=-30.4/17.9/68.4, Antsiranana=-27.0/25.2/75.8, Arkhangelsk=-52.3/1.3/50.5, Ashgabat=-35.3/17.1/67.8, Asmara=-35.3/15.6/64.2, Assab=-27.5/30.5/81.6, Astana=-47.5/3.5/53.3, Athens=-32.2/19.2/67.5, Atlanta=-33.2/17.0/66.1, Auckland=-37.4/15.2/63.9, Austin=-29.0/20.7/73.7, Baghdad=-30.8/22.8/70.6, Baguio=-32.7/19.5/72.4, Baku=-34.7/15.1/66.2, Baltimore=-38.2/13.1/61.2, Bamako=-23.2/27.8/76.9, Bangkok=-20.5/28.6/80.0, Bangui=-25.4/26.0/73.9, Banjul=-27.3/26.0/74.0, Barcelona=-31.5/18.2/74.2, Bata=-27.9/25.1/75.2, Batumi=-34.6/14.0/63.1, Beijing=-37.9/12.9/60.9, Beirut=-30.6/20.9/71.0, Belgrade=-42.1/12.5/63.0, Belize City=-26.1/26.7/75.4, Benghazi=-29.1/19.9/68.6, Bergen=-45.9/7.7/60.4, Berlin=-42.5/10.3/59.9, Bilbao=-42.8/14.7/66.7, Birao=-21.2/26.5/75.6, Bishkek=-38.1/11.3/61.4, Bissau=-19.7/27.0/76.6, Blantyre=-27.1/22.2/69.5, Bloemfontein=-36.3/15.6/67.2, Boise=-39.6/11.4/61.0, Bordeaux=-34.6/14.2/63.2, Bosaso=-16.4/30.0/78.1, Boston=-43.9/10.9/59.0, Bouaké=-27.5/26.0/77.2, Bratislava=-40.8/10.5/60.4, Brazzaville=-24.2/25.0/76.0, Bridgetown=-26.8/27.0/75.3, Brisbane=-30.0/21.4/71.7, Brussels=-41.9/10.5/63.0, Bucharest=-37.5/10.8/59.1, Budapest=-40.2/11.3/59.1, Bujumbura=-25.1/23.8/74.6, Bulawayo=-39.0/18.9/69.2, Burnie=-38.6/13.1/60.2, Busan=-34.8/15.0/66.2, Cabo San Lucas=-23.6/23.9/72.5, Cairns=-32.9/25.0/76.5, Cairo=-31.5/21.4/69.4, Calgary=-44.4/4.4/56.4, Canberra=-34.6/13.1/68.1, Cape Town=-34.7/16.2/70.1, Changsha=-31.8/17.4/68.4, Charlotte=-32.1/16.1/65.9, Chiang Mai=-24.5/25.8/74.8, Chicago=-40.9/9.8/60.4, Chihuahua=-30.5/18.6/66.3, Chittagong=-22.4/25.9/75.0, Chișinău=-41.1/10.2/61.7, Chongqing=-32.1/18.6/74.2, Christchurch=-38.6/12.2/63.0, City of San Marino=-37.1/11.8/61.8, Colombo=-23.2/27.4/77.1, Columbus=-37.3/11.7/64.9, Conakry=-21.9/26.4/76.5, Copenhagen=-39.5/9.1/58.3, Cotonou=-22.8/27.2/78.0, Cracow=-44.4/9.3/57.6, Da Lat=-29.4/17.9/67.8, Da Nang=-24.3/25.8/76.5, Dakar=-33.6/24.0/74.7, Dallas=-36.0/19.0/68.2, Damascus=-33.0/17.0/68.7, Dampier=-30.0/26.4/74.0, Dar es Salaam=-29.5/25.8/72.5, Darwin=-21.5/27.6/77.2, Denpasar=-22.6/23.7/73.0, Denver=-43.9/10.4/58.2, Detroit=-39.9/10.0/59.9, Dhaka=-21.8/25.9/73.5, Dikson=-65.9/-11.1/37.2, Dili=-20.8/26.6/75.4, Djibouti=-20.9/29.9/84.0, Dodoma=-27.8/22.7/73.1, Dolisie=-23.0/24.0/77.1, Douala=-19.4/26.7/76.4, Dubai=-22.4/26.9/76.4, Dublin=-40.9/9.8/66.4, Dunedin=-41.6/11.1/58.8, Durban=-36.4/20.6/69.2, Dushanbe=-34.7/14.7/63.6, Edinburgh=-37.6/9.3/60.0, Edmonton=-45.0/4.2/53.7, El Paso=-33.3/18.1/73.6, Entebbe=-31.3/21.0/71.6, Erbil=-32.3/19.5/66.1, Erzurum=-49.7/5.1/53.4, Fairbanks=-50.5/-2.3/46.3, Fianarantsoa=-32.6/17.9/71.9, Flores, Petén=-21.3/26.4/76.2, Frankfurt=-38.1/10.6/60.9, Fresno=-29.5/17.9/68.7, Fukuoka=-33.1/17.0/68.2, Gaborone=-26.7/21.0/69.7, Gabès=-29.3/19.5/74.6, Gagnoa=-25.4/26.0/77.5, Gangtok=-34.3/15.2/64.3, Garissa=-20.6/29.3/78.3, Garoua=-20.7/28.3/78.1, George Town=-22.5/27.9/84.2, Ghanzi=-27.8/21.4/72.2, Gjoa Haven=-64.4/-14.4/32.8, Guadalajara=-29.6/20.9/72.6, Guangzhou=-25.7/22.4/70.3, Guatemala City=-29.9/20.4/71.9, Halifax=-41.7/7.5/57.0, Hamburg=-41.9/9.7/58.9, Hamilton=-37.5/13.8/63.7, Hanga Roa=-27.6/20.5/70.8, Hanoi=-29.5/23.6/72.6, Harare=-28.8/18.4/65.8, Harbin=-43.4/5.0/54.9, Hargeisa=-28.6/21.7/71.8, Hat Yai=-24.9/27.0/77.9, Havana=-23.7/25.2/77.5, Helsinki=-47.9/5.9/59.5, Heraklion=-31.1/18.9/70.9, Hiroshima=-30.5/16.3/65.2, Ho Chi Minh City=-24.3/27.4/77.9, Hobart=-35.6/12.7/63.1, Hong Kong=-23.3/23.3/76.9, Honiara=-28.3/26.5/84.3, Honolulu=-23.9/25.4/77.2, Houston=-30.3/20.8/73.3, Ifrane=-36.9/11.4/62.7, Indianapolis=-38.0/11.8/68.8, Iqaluit=-58.7/-9.3/42.5, Irkutsk=-47.7/1.0/57.0, Istanbul=-37.6/13.9/62.9, Jacksonville=-35.5/20.3/67.3, Jakarta=-26.1/26.7/75.5, Jayapura=-22.7/27.0/73.8, Jerusalem=-29.2/18.3/70.4, Johannesburg=-34.4/15.5/63.0, Jos=-27.0/22.8/74.0, Juba=-20.7/27.8/76.7, Kabul=-38.8/12.1/58.7, Kampala=-28.7/20.0/68.9, Kandi=-26.0/27.7/77.4, Kankan=-23.3/26.5/77.6, Kano=-21.9/26.4/74.1, Kansas City=-40.7/12.5/65.2, Karachi=-23.1/26.0/72.6, Karonga=-24.2/24.4/72.9, Kathmandu=-36.0/18.3/69.0, Khartoum=-21.8/29.9/80.3, Kingston=-19.2/27.4/78.8, Kinshasa=-23.8/25.3/75.6, Kolkata=-24.4/26.7/78.5, Kuala Lumpur=-22.0/27.3/77.7, Kumasi=-25.2/26.0/73.4, Kunming=-34.8/15.7/67.0, Kuopio=-50.0/3.4/49.3, Kuwait City=-26.8/25.7/77.8, Kyiv=-38.9/8.4/56.9, Kyoto=-36.9/15.8/66.7, La Ceiba=-23.5/26.2/78.0, La Paz=-23.3/23.7/75.4, Lagos=-22.8/26.8/77.0, Lahore=-28.1/24.3/71.7, Lake Havasu City=-28.5/23.7/72.4, Lake Tekapo=-39.0/8.7/65.6, Las Palmas de Gran Canaria=-28.8/21.2/73.0, Las Vegas=-29.9/20.3/69.9, Launceston=-36.8/13.1/62.7, Lhasa=-43.6/7.6/57.9, Libreville=-23.4/25.9/74.4, Lisbon=-35.5/17.5/65.8, Livingstone=-26.0/21.8/70.5, Ljubljana=-38.9/10.9/62.4, Lodwar=-18.9/29.3/78.3, Lomé=-22.2/26.9/76.0, London=-43.1/11.3/61.6, Los Angeles=-29.2/18.6/74.2, Louisville=-35.6/13.9/64.0, Luanda=-22.5/25.8/73.0, Lubumbashi=-28.8/20.8/70.0, Lusaka=-28.0/19.9/67.3, Luxembourg City=-43.2/9.3/62.4, Lviv=-41.3/7.8/55.1, Lyon=-37.3/12.5/59.9, Madrid=-34.2/15.0/63.1, Mahajanga=-29.1/26.3/75.4, Makassar=-27.0/26.7/75.2, Makurdi=-25.1/26.0/72.7, Malabo=-21.0/26.3/78.0, Malé=-22.6/28.0/78.5, Managua=-24.6/27.3/78.5, Manama=-21.0/26.5/79.4, Mandalay=-24.3/28.0/75.9, Mango=-20.6/28.1/75.6, Manila=-26.1/28.4/77.5, Maputo=-25.1/22.8/70.8, Marrakesh=-31.5/19.6/69.2, Marseille=-33.7/15.8/66.1, Maun=-28.9/22.4/69.8, Medan=-23.0/26.5/79.2, Mek'ele=-28.4/22.7/71.5, Melbourne=-34.1/15.1/65.7, Memphis=-38.9/17.2/68.9, Mexicali=-26.3/23.1/72.1, Mexico City=-29.3/17.5/68.0, Miami=-22.4/24.9/78.8, Milan=-36.0/13.0/68.5, Milwaukee=-40.3/8.9/60.8, Minneapolis=-40.9/7.8/58.0, Minsk=-42.2/6.7/55.8, Mogadishu=-21.7/27.1/79.5, Mombasa=-22.5/26.3/76.5, Monaco=-35.1/16.4/63.7, Moncton=-40.7/6.1/54.4, Monterrey=-31.2/22.3/70.8, Montreal=-43.8/6.8/57.3, Moscow=-44.5/5.8/52.8, Mumbai=-23.4/27.1/78.5, Murmansk=-49.3/0.6/51.3, Muscat=-20.1/28.0/77.8, Mzuzu=-33.3/17.7/66.7, N'Djamena=-19.6/28.3/79.4, Naha=-24.2/23.1/75.7, Nairobi=-32.9/17.8/66.1, Nakhon Ratchasima=-20.4/27.3/81.4, Napier=-36.2/14.6/64.8, Napoli=-35.2/15.9/65.3, Nashville=-35.5/15.4/63.4, Nassau=-25.0/24.6/76.8, Ndola=-31.1/20.3/73.0, New Delhi=-25.1/25.0/73.2, New Orleans=-26.8/20.7/72.9, New York City=-35.7/12.9/66.4, Ngaoundéré=-28.7/22.0/68.7, Niamey=-21.9/29.3/79.8, Nicosia=-29.2/19.7/69.8, Niigata=-36.6/13.9/63.8, Nouadhibou=-27.7/21.3/69.7, Nouakchott=-29.0/25.7/76.4, Novosibirsk=-45.8/1.7/48.5, Nuuk=-55.4/-1.4/51.2, Odesa=-40.9/10.7/61.1, Odienné=-24.1/26.0/74.3, Oklahoma City=-30.8/15.9/67.0, Omaha=-37.8/10.6/60.3, Oranjestad=-21.0/28.1/80.5, Oslo=-40.9/5.7/54.4, Ottawa=-40.0/6.6/55.3, Ouagadougou=-23.4/28.3/79.2, Ouahigouya=-21.8/28.6/78.8, Ouarzazate=-31.4/18.9/67.1, Oulu=-52.5/2.7/52.1, Palembang=-19.9/27.3/76.9, Palermo=-31.4/18.5/72.2, Palm Springs=-27.0/24.5/73.3, Palmerston North=-37.4/13.2/66.5, Panama City=-26.9/28.0/76.0, Parakou=-21.2/26.8/76.0, Paris=-35.9/12.3/64.8, Perth=-32.0/18.7/64.9, Petropavlovsk-Kamchatsky=-48.0/1.9/52.1, Philadelphia=-37.0/13.2/65.1, Phnom Penh=-19.9/28.3/77.7, Phoenix=-25.9/23.9/70.3, Pittsburgh=-42.5/10.8/58.8, Podgorica=-32.6/15.3/64.7, Pointe-Noire=-23.4/26.1/82.4, Pontianak=-21.7/27.7/86.7, Port Moresby=-22.3/26.9/78.2, Port Sudan=-21.1/28.4/76.4, Port Vila=-23.0/24.3/74.9, Port-Gentil=-21.5/26.0/78.7, Portland (OR)=-35.3/12.4/63.5, Porto=-31.5/15.7/62.1, Prague=-47.7/8.4/58.0, Praia=-26.3/24.4/74.2, Pretoria=-36.2/18.2/66.2, Pyongyang=-39.2/10.8/63.3, Rabat=-32.0/17.2/64.7, Rangpur=-27.6/24.4/70.1, Reggane=-19.9/28.3/77.9, Reykjavík=-46.9/4.3/52.9, Riga=-44.9/6.2/56.0, Riyadh=-23.4/26.0/78.7, Rome=-34.9/15.2/64.0, Roseau=-23.0/26.2/76.7, Rostov-on-Don=-45.2/9.9/58.9, Sacramento=-34.7/16.3/68.6, Saint Petersburg=-42.6/5.8/53.8, Saint-Pierre=-44.8/5.7/56.7, Salt Lake City=-36.9/11.6/60.0, San Antonio=-27.8/20.8/69.1, San Diego=-33.1/17.8/67.1, San Francisco=-40.8/14.6/63.6, San Jose=-30.7/16.4/67.7, San José=-26.5/22.6/75.2, San Juan=-23.6/27.2/78.0, San Salvador=-32.6/23.1/74.4, Sana'a=-28.7/20.0/69.2, Santo Domingo=-23.6/25.9/76.7, Sapporo=-42.8/8.9/60.3, Sarajevo=-39.5/10.1/60.5, Saskatoon=-46.8/3.3/52.2, Seattle=-40.8/11.3/61.4, Seoul=-35.3/12.5/61.7, Seville=-31.2/19.2/70.4, Shanghai=-32.9/16.7/67.6, Singapore=-22.7/27.0/77.4, Skopje=-37.3/12.4/60.6, Sochi=-31.5/14.2/65.1, Sofia=-45.0/10.6/61.8, Sokoto=-20.1/28.0/76.9, Split=-35.7/16.1/66.0, St. John's=-45.4/5.0/50.8, St. Louis=-37.6/13.9/66.7, Stockholm=-47.1/6.6/55.5, Surabaya=-28.4/27.1/76.0, Suva=-29.1/25.6/74.1, Suwałki=-43.6/7.2/55.0, Sydney=-31.3/17.7/69.2, Ségou=-23.4/28.0/74.4, Tabora=-28.2/23.0/71.5, Tabriz=-38.1/12.6/68.4, Taipei=-28.8/23.0/70.1, Tallinn=-45.6/6.4/52.7, Tamale=-20.3/27.9/76.5, Tamanrasset=-27.1/21.7/69.5, Tampa=-29.8/22.9/71.5, Tashkent=-34.4/14.8/63.9, Tauranga=-34.9/14.8/64.5, Tbilisi=-39.1/12.9/61.9, Tegucigalpa=-34.3/21.7/69.5, Tehran=-32.2/17.0/71.3, Tel Aviv=-29.8/20.0/69.4, Thessaloniki=-33.2/16.0/68.5, Thiès=-27.0/24.0/76.8, Tijuana=-36.6/17.8/66.7, Timbuktu=-20.4/28.0/80.1, Tirana=-36.3/15.2/64.3, Toamasina=-25.5/23.4/76.7, Tokyo=-40.6/15.4/66.8, Toliara=-25.2/24.1/73.2, Toluca=-42.8/12.4/62.4, Toronto=-44.8/9.4/58.1, Tripoli=-34.6/20.0/75.1, Tromsø=-45.7/2.9/53.5, Tucson=-30.1/20.9/70.5, Tunis=-31.5/18.4/68.0, Ulaanbaatar=-47.8/-0.4/49.7, Upington=-30.1/20.4/73.3, Vaduz=-38.4/10.1/58.4, Valencia=-29.5/18.3/73.5, Valletta=-31.6/18.8/70.9, Vancouver=-38.0/10.4/62.7, Veracruz=-26.8/25.4/78.0, Vienna=-39.7/10.4/62.2, Vientiane=-26.9/25.9/78.2, Villahermosa=-22.0/27.1/74.1, Vilnius=-44.1/6.0/55.0, Virginia Beach=-34.0/15.8/67.0, Vladivostok=-45.1/4.9/56.4, Warsaw=-40.5/8.5/56.3, Washington, D.C.=-33.1/14.6/64.4, Wau=-24.6/27.8/77.5, Wellington=-34.1/12.9/65.5, Whitehorse=-52.5/-0.1/47.5, Wichita=-39.0/13.9/64.6, Willemstad=-22.2/28.0/77.7, Winnipeg=-47.1/3.0/50.6, Wrocław=-42.4/9.6/59.3, Xi'an=-35.8/14.1/62.0, Yakutsk=-59.9/-8.8/41.9, Yangon=-27.6/27.5/76.1, Yaoundé=-28.6/23.8/72.9, Yellowknife=-55.7/-4.3/49.2, Yerevan=-37.2/12.4/67.7, Yinchuan=-39.4/9.0/62.1, Zagreb=-38.9/10.7/62.2, Zanzibar City=-24.6/26.0/78.6, Zürich=-44.3/9.3/59.4, Ürümqi=-43.3/7.4/59.1, İzmir=-30.7/17.9/68.5}
Parallelised: 56.377148167s
{Abha=-31.3/18.0/67.4, Abidjan=-26.9/26.0/75.5, Abéché=-23.4/29.4/81.5, Accra=-24.7/26.4/78.4, Addis Ababa=-30.9/16.0/65.5, Adelaide=-33.8/17.3/65.0, Aden=-22.6/29.1/78.1, Ahvaz=-22.1/25.4/75.1, Albuquerque=-39.2/14.0/61.5, Alexandra=-40.0/11.0/60.9, Alexandria=-27.9/20.0/69.2, Algiers=-33.0/18.2/70.9, Alice Springs=-27.1/21.0/70.5, Almaty=-37.9/10.0/58.3, Amsterdam=-38.6/10.2/60.7, Anadyr=-60.7/-6.9/42.8, Anchorage=-45.8/2.8/50.6, Andorra la Vella=-40.0/9.8/57.4, Ankara=-36.8/12.0/62.5, Antananarivo=-30.4/17.9/68.4, Antsiranana=-27.0/25.2/75.8, Arkhangelsk=-52.3/1.3/50.5, Ashgabat=-35.3/17.1/67.8, Asmara=-35.3/15.6/64.2, Assab=-27.5/30.5/81.6, Astana=-47.5/3.5/53.3, Athens=-32.2/19.2/67.5, Atlanta=-33.2/17.0/66.1, Auckland=-37.4/15.2/63.9, Austin=-29.0/20.7/73.7, Baghdad=-30.8/22.8/70.6, Baguio=-32.7/19.5/72.4, Baku=-34.7/15.1/66.2, Baltimore=-38.2/13.1/61.2, Bamako=-23.2/27.8/76.9, Bangkok=-20.5/28.6/80.0, Bangui=-25.4/26.0/73.9, Banjul=-27.3/26.0/74.0, Barcelona=-31.5/18.2/74.2, Bata=-27.9/25.1/75.2, Batumi=-34.6/14.0/63.1, Beijing=-37.9/12.9/60.9, Beirut=-30.6/20.9/71.0, Belgrade=-42.1/12.5/63.0, Belize City=-26.1/26.7/75.4, Benghazi=-29.1/19.9/68.6, Bergen=-45.9/7.7/60.4, Berlin=-42.5/10.3/59.9, Bilbao=-42.8/14.7/66.7, Birao=-21.2/26.5/75.6, Bishkek=-38.1/11.3/61.4, Bissau=-19.7/27.0/76.6, Blantyre=-27.1/22.2/69.5, Bloemfontein=-36.3/15.6/67.2, Boise=-39.6/11.4/61.0, Bordeaux=-34.6/14.2/63.2, Bosaso=-16.4/30.0/78.1, Boston=-43.9/10.9/59.0, Bouaké=-27.5/26.0/77.2, Bratislava=-40.8/10.5/60.4, Brazzaville=-24.2/25.0/76.0, Bridgetown=-26.8/27.0/75.3, Brisbane=-30.0/21.4/71.7, Brussels=-41.9/10.5/63.0, Bucharest=-37.5/10.8/59.1, Budapest=-40.2/11.3/59.1, Bujumbura=-25.1/23.8/74.6, Bulawayo=-39.0/18.9/69.2, Burnie=-38.6/13.1/60.2, Busan=-34.8/15.0/66.2, Cabo San Lucas=-23.6/23.9/72.5, Cairns=-32.9/25.0/76.5, Cairo=-31.5/21.4/69.4, Calgary=-44.4/4.4/56.4, Canberra=-34.6/13.1/68.1, Cape Town=-34.7/16.2/70.1, Changsha=-31.8/17.4/68.4, Charlotte=-32.1/16.1/65.9, Chiang Mai=-24.5/25.8/74.8, Chicago=-40.9/9.8/60.4, Chihuahua=-30.5/18.6/66.3, Chittagong=-22.4/25.9/75.0, Chișinău=-41.1/10.2/61.7, Chongqing=-32.1/18.6/74.2, Christchurch=-38.6/12.2/63.0, City of San Marino=-37.1/11.8/61.8, Colombo=-23.2/27.4/77.1, Columbus=-37.3/11.7/64.9, Conakry=-21.9/26.4/76.5, Copenhagen=-39.5/9.1/58.3, Cotonou=-22.8/27.2/78.0, Cracow=-44.4/9.3/57.6, Da Lat=-29.4/17.9/67.8, Da Nang=-24.3/25.8/76.5, Dakar=-33.6/24.0/74.7, Dallas=-36.0/19.0/68.2, Damascus=-33.0/17.0/68.7, Dampier=-30.0/26.4/74.0, Dar es Salaam=-29.5/25.8/72.5, Darwin=-21.5/27.6/77.2, Denpasar=-22.6/23.7/73.0, Denver=-43.9/10.4/58.2, Detroit=-39.9/10.0/59.9, Dhaka=-21.8/25.9/73.5, Dikson=-65.9/-11.1/37.2, Dili=-20.8/26.6/75.4, Djibouti=-20.9/29.9/84.0, Dodoma=-27.8/22.7/73.1, Dolisie=-23.0/24.0/77.1, Douala=-19.4/26.7/76.4, Dubai=-22.4/26.9/76.4, Dublin=-40.9/9.8/66.4, Dunedin=-41.6/11.1/58.8, Durban=-36.4/20.6/69.2, Dushanbe=-34.7/14.7/63.6, Edinburgh=-37.6/9.3/60.0, Edmonton=-45.0/4.2/53.7, El Paso=-33.3/18.1/73.6, Entebbe=-31.3/21.0/71.6, Erbil=-32.3/19.5/66.1, Erzurum=-49.7/5.1/53.4, Fairbanks=-50.5/-2.3/46.3, Fianarantsoa=-32.6/17.9/71.9, Flores, Petén=-21.3/26.4/76.2, Frankfurt=-38.1/10.6/60.9, Fresno=-29.5/17.9/68.7, Fukuoka=-33.1/17.0/68.2, Gaborone=-26.7/21.0/69.7, Gabès=-29.3/19.5/74.6, Gagnoa=-25.4/26.0/77.5, Gangtok=-34.3/15.2/64.3, Garissa=-20.6/29.3/78.3, Garoua=-20.7/28.3/78.1, George Town=-22.5/27.9/84.2, Ghanzi=-27.8/21.4/72.2, Gjoa Haven=-64.4/-14.4/32.8, Guadalajara=-29.6/20.9/72.6, Guangzhou=-25.7/22.4/70.3, Guatemala City=-29.9/20.4/71.9, Halifax=-41.7/7.5/57.0, Hamburg=-41.9/9.7/58.9, Hamilton=-37.5/13.8/63.7, Hanga Roa=-27.6/20.5/70.8, Hanoi=-29.5/23.6/72.6, Harare=-28.8/18.4/65.8, Harbin=-43.4/5.0/54.9, Hargeisa=-28.6/21.7/71.8, Hat Yai=-24.9/27.0/77.9, Havana=-23.7/25.2/77.5, Helsinki=-47.9/5.9/59.5, Heraklion=-31.1/18.9/70.9, Hiroshima=-30.5/16.3/65.2, Ho Chi Minh City=-24.3/27.4/77.9, Hobart=-35.6/12.7/63.1, Hong Kong=-23.3/23.3/76.9, Honiara=-28.3/26.5/84.3, Honolulu=-23.9/25.4/77.2, Houston=-30.3/20.8/73.3, Ifrane=-36.9/11.4/62.7, Indianapolis=-38.0/11.8/68.8, Iqaluit=-58.7/-9.3/42.5, Irkutsk=-47.7/1.0/57.0, Istanbul=-37.6/13.9/62.9, Jacksonville=-35.5/20.3/67.3, Jakarta=-26.1/26.7/75.5, Jayapura=-22.7/27.0/73.8, Jerusalem=-29.2/18.3/70.4, Johannesburg=-34.4/15.5/63.0, Jos=-27.0/22.8/74.0, Juba=-20.7/27.8/76.7, Kabul=-38.8/12.1/58.7, Kampala=-28.7/20.0/68.9, Kandi=-26.0/27.7/77.4, Kankan=-23.3/26.5/77.6, Kano=-21.9/26.4/74.1, Kansas City=-40.7/12.5/65.2, Karachi=-23.1/26.0/72.6, Karonga=-24.2/24.4/72.9, Kathmandu=-36.0/18.3/69.0, Khartoum=-21.8/29.9/80.3, Kingston=-19.2/27.4/78.8, Kinshasa=-23.8/25.3/75.6, Kolkata=-24.4/26.7/78.5, Kuala Lumpur=-22.0/27.3/77.7, Kumasi=-25.2/26.0/73.4, Kunming=-34.8/15.7/67.0, Kuopio=-50.0/3.4/49.3, Kuwait City=-26.8/25.7/77.8, Kyiv=-38.9/8.4/56.9, Kyoto=-36.9/15.8/66.7, La Ceiba=-23.5/26.2/78.0, La Paz=-23.3/23.7/75.4, Lagos=-22.8/26.8/77.0, Lahore=-28.1/24.3/71.7, Lake Havasu City=-28.5/23.7/72.4, Lake Tekapo=-39.0/8.7/65.6, Las Palmas de Gran Canaria=-28.8/21.2/73.0, Las Vegas=-29.9/20.3/69.9, Launceston=-36.8/13.1/62.7, Lhasa=-43.6/7.6/57.9, Libreville=-23.4/25.9/74.4, Lisbon=-35.5/17.5/65.8, Livingstone=-26.0/21.8/70.5, Ljubljana=-38.9/10.9/62.4, Lodwar=-18.9/29.3/78.3, Lomé=-22.2/26.9/76.0, London=-43.1/11.3/61.6, Los Angeles=-29.2/18.6/74.2, Louisville=-35.6/13.9/64.0, Luanda=-22.5/25.8/73.0, Lubumbashi=-28.8/20.8/70.0, Lusaka=-28.0/19.9/67.3, Luxembourg City=-43.2/9.3/62.4, Lviv=-41.3/7.8/55.1, Lyon=-37.3/12.5/59.9, Madrid=-34.2/15.0/63.1, Mahajanga=-29.1/26.3/75.4, Makassar=-27.0/26.7/75.2, Makurdi=-25.1/26.0/72.7, Malabo=-21.0/26.3/78.0, Malé=-22.6/28.0/78.5, Managua=-24.6/27.3/78.5, Manama=-21.0/26.5/79.4, Mandalay=-24.3/28.0/75.9, Mango=-20.6/28.1/75.6, Manila=-26.1/28.4/77.5, Maputo=-25.1/22.8/70.8, Marrakesh=-31.5/19.6/69.2, Marseille=-33.7/15.8/66.1, Maun=-28.9/22.4/69.8, Medan=-23.0/26.5/79.2, Mek'ele=-28.4/22.7/71.5, Melbourne=-34.1/15.1/65.7, Memphis=-38.9/17.2/68.9, Mexicali=-26.3/23.1/72.1, Mexico City=-29.3/17.5/68.0, Miami=-22.4/24.9/78.8, Milan=-36.0/13.0/68.5, Milwaukee=-40.3/8.9/60.8, Minneapolis=-40.9/7.8/58.0, Minsk=-42.2/6.7/55.8, Mogadishu=-21.7/27.1/79.5, Mombasa=-22.5/26.3/76.5, Monaco=-35.1/16.4/63.7, Moncton=-40.7/6.1/54.4, Monterrey=-31.2/22.3/70.8, Montreal=-43.8/6.8/57.3, Moscow=-44.5/5.8/52.8, Mumbai=-23.4/27.1/78.5, Murmansk=-49.3/0.6/51.3, Muscat=-20.1/28.0/77.8, Mzuzu=-33.3/17.7/66.7, N'Djamena=-19.6/28.3/79.4, Naha=-24.2/23.1/75.7, Nairobi=-32.9/17.8/66.1, Nakhon Ratchasima=-20.4/27.3/81.4, Napier=-36.2/14.6/64.8, Napoli=-35.2/15.9/65.3, Nashville=-35.5/15.4/63.4, Nassau=-25.0/24.6/76.8, Ndola=-31.1/20.3/73.0, New Delhi=-25.1/25.0/73.2, New Orleans=-26.8/20.7/72.9, New York City=-35.7/12.9/66.4, Ngaoundéré=-28.7/22.0/68.7, Niamey=-21.9/29.3/79.8, Nicosia=-29.2/19.7/69.8, Niigata=-36.6/13.9/63.8, Nouadhibou=-27.7/21.3/69.7, Nouakchott=-29.0/25.7/76.4, Novosibirsk=-45.8/1.7/48.5, Nuuk=-55.4/-1.4/51.2, Odesa=-40.9/10.7/61.1, Odienné=-24.1/26.0/74.3, Oklahoma City=-30.8/15.9/67.0, Omaha=-37.8/10.6/60.3, Oranjestad=-21.0/28.1/80.5, Oslo=-40.9/5.7/54.4, Ottawa=-40.0/6.6/55.3, Ouagadougou=-23.4/28.3/79.2, Ouahigouya=-21.8/28.6/78.8, Ouarzazate=-31.4/18.9/67.1, Oulu=-52.5/2.7/52.1, Palembang=-19.9/27.3/76.9, Palermo=-31.4/18.5/72.2, Palm Springs=-27.0/24.5/73.3, Palmerston North=-37.4/13.2/66.5, Panama City=-26.9/28.0/76.0, Parakou=-21.2/26.8/76.0, Paris=-35.9/12.3/64.8, Perth=-32.0/18.7/64.9, Petropavlovsk-Kamchatsky=-48.0/1.9/52.1, Philadelphia=-37.0/13.2/65.1, Phnom Penh=-19.9/28.3/77.7, Phoenix=-25.9/23.9/70.3, Pittsburgh=-42.5/10.8/58.8, Podgorica=-32.6/15.3/64.7, Pointe-Noire=-23.4/26.1/82.4, Pontianak=-21.7/27.7/86.7, Port Moresby=-22.3/26.9/78.2, Port Sudan=-21.1/28.4/76.4, Port Vila=-23.0/24.3/74.9, Port-Gentil=-21.5/26.0/78.7, Portland (OR)=-35.3/12.4/63.5, Porto=-31.5/15.7/62.1, Prague=-47.7/8.4/58.0, Praia=-26.3/24.4/74.2, Pretoria=-36.2/18.2/66.2, Pyongyang=-39.2/10.8/63.3, Rabat=-32.0/17.2/64.7, Rangpur=-27.6/24.4/70.1, Reggane=-19.9/28.3/77.9, Reykjavík=-46.9/4.3/52.9, Riga=-44.9/6.2/56.0, Riyadh=-23.4/26.0/78.7, Rome=-34.9/15.2/64.0, Roseau=-23.0/26.2/76.7, Rostov-on-Don=-45.2/9.9/58.9, Sacramento=-34.7/16.3/68.6, Saint Petersburg=-42.6/5.8/53.8, Saint-Pierre=-44.8/5.7/56.7, Salt Lake City=-36.9/11.6/60.0, San Antonio=-27.8/20.8/69.1, San Diego=-33.1/17.8/67.1, San Francisco=-40.8/14.6/63.6, San Jose=-30.7/16.4/67.7, San José=-26.5/22.6/75.2, San Juan=-23.6/27.2/78.0, San Salvador=-32.6/23.1/74.4, Sana'a=-28.7/20.0/69.2, Santo Domingo=-23.6/25.9/76.7, Sapporo=-42.8/8.9/60.3, Sarajevo=-39.5/10.1/60.5, Saskatoon=-46.8/3.3/52.2, Seattle=-40.8/11.3/61.4, Seoul=-35.3/12.5/61.7, Seville=-31.2/19.2/70.4, Shanghai=-32.9/16.7/67.6, Singapore=-22.7/27.0/77.4, Skopje=-37.3/12.4/60.6, Sochi=-31.5/14.2/65.1, Sofia=-45.0/10.6/61.8, Sokoto=-20.1/28.0/76.9, Split=-35.7/16.1/66.0, St. John's=-45.4/5.0/50.8, St. Louis=-37.6/13.9/66.7, Stockholm=-47.1/6.6/55.5, Surabaya=-28.4/27.1/76.0, Suva=-29.1/25.6/74.1, Suwałki=-43.6/7.2/55.0, Sydney=-31.3/17.7/69.2, Ségou=-23.4/28.0/74.4, Tabora=-28.2/23.0/71.5, Tabriz=-38.1/12.6/68.4, Taipei=-28.8/23.0/70.1, Tallinn=-45.6/6.4/52.7, Tamale=-20.3/27.9/76.5, Tamanrasset=-27.1/21.7/69.5, Tampa=-29.8/22.9/71.5, Tashkent=-34.4/14.8/63.9, Tauranga=-34.9/14.8/64.5, Tbilisi=-39.1/12.9/61.9, Tegucigalpa=-34.3/21.7/69.5, Tehran=-32.2/17.0/71.3, Tel Aviv=-29.8/20.0/69.4, Thessaloniki=-33.2/16.0/68.5, Thiès=-27.0/24.0/76.8, Tijuana=-36.6/17.8/66.7, Timbuktu=-20.4/28.0/80.1, Tirana=-36.3/15.2/64.3, Toamasina=-25.5/23.4/76.7, Tokyo=-40.6/15.4/66.8, Toliara=-25.2/24.1/73.2, Toluca=-42.8/12.4/62.4, Toronto=-44.8/9.4/58.1, Tripoli=-34.6/20.0/75.1, Tromsø=-45.7/2.9/53.5, Tucson=-30.1/20.9/70.5, Tunis=-31.5/18.4/68.0, Ulaanbaatar=-47.8/-0.4/49.7, Upington=-30.1/20.4/73.3, Vaduz=-38.4/10.1/58.4, Valencia=-29.5/18.3/73.5, Valletta=-31.6/18.8/70.9, Vancouver=-38.0/10.4/62.7, Veracruz=-26.8/25.4/78.0, Vienna=-39.7/10.4/62.2, Vientiane=-26.9/25.9/78.2, Villahermosa=-22.0/27.1/74.1, Vilnius=-44.1/6.0/55.0, Virginia Beach=-34.0/15.8/67.0, Vladivostok=-45.1/4.9/56.4, Warsaw=-40.5/8.5/56.3, Washington, D.C.=-33.1/14.6/64.4, Wau=-24.6/27.8/77.5, Wellington=-34.1/12.9/65.5, Whitehorse=-52.5/-0.1/47.5, Wichita=-39.0/13.9/64.6, Willemstad=-22.2/28.0/77.7, Winnipeg=-47.1/3.0/50.6, Wrocław=-42.4/9.6/59.3, Xi'an=-35.8/14.1/62.0, Yakutsk=-59.9/-8.8/41.9, Yangon=-27.6/27.5/76.1, Yaoundé=-28.6/23.8/72.9, Yellowknife=-55.7/-4.3/49.2, Yerevan=-37.2/12.4/67.7, Yinchuan=-39.4/9.0/62.1, Zagreb=-38.9/10.7/62.2, Zanzibar City=-24.6/26.0/78.6, Zürich=-44.3/9.3/59.4, Ürümqi=-43.3/7.4/59.1, İzmir=-30.7/17.9/68.5}
ojAlgo: 16.335035291s
Interpretation
Just making the baseline’s stream parallel made things 3 times faster, but that’s on an 8-core machine.
The ojAlgo-based version is 10 times faster (using 8-cores). Apart from more efficient parallelism the ojAlgo-based version also uses a custom function to parse a portion of a String to a double.
So we, easily, made it 10 times faster. The 1BRC demonstrated that it is possible to make it 100 times faster, but then you have to write very different code.
However impressive the results of the challenge are, one should remember that it is an extremely simplified/specialised case. With a few minor modifications to the challenge, it would be a very different task, and it would not be possible to get such fast execution times. What if:
- The data file contained more/other data than what we needed?
- We needed to support varying formats of the temperature measurements (varying number of decimals, scientific format…)?
- Perhaps a few errors (bad data) in the file?
- The statistics were required to contain the median or similar?
- 1 billion rows and up to 10k stations/cities, but in fact there was only 413 stations used in data set used to benchmark. What if there were many millions of stations?
- Then perhaps, the final stage was to perform some further calculations based on the statistics…
Also, this performance challenge was not using JMH to benchmark/compare the different implementations. It was executed as a one-shot bursts. That, I assume, favours GraalVM native binary.
- ← Previous
Image Processing using FFT - Next →
Mall Customer Segmentation