ใน Java 8 ขึ้นมานั้น (นานแล้ว)
มี Stream API เพิ่มเข้ามา
ทำให้ง่ายต่อการเข้าถึงข้อมูลในรูปแบบของ collection
โดยไม่ทำการแก้ไขข้อมูลต้นทางหรือต้นฉบับ
สามารถทำซ้ำแล้วซ้ำเล่า
จะได้ผลเช่นเดิม ใน operation เดิมเสมอ
ซึ่งการใช้งานสามารถสร้าง stream ในรูปแบบของ sequential
หรือ parallel (ตาม core ของ CPU) ก็ได้

คำถามที่น่าสนใจคือ

เมื่อใดควรใช้ sequential stream ?
เมื่อใดควรใช้ parallel stream ?

ก่อนที่จะเลือกว่าจะใช้อะไรนั้น
ควรทำความเข้าใจแต่ละอย่างก่อนว่าเป็นอย่างไร ?

พื้นฐานของ Stream คือตัวหุ้มหรือ wrapper ของ data source นั่นเอง
ช่วยให้เราสามารถทำงานหรือ operation ต่าง ๆ บน data source ได้อย่างง่าย
หรือเรียกว่าการเพิ่ม operation บน data pipeline

Sequential stream คืออะไร

เป็นค่า default สำหรับ Stream นั่นเอง
โดยที่ operation ต่าง ๆ จะทำงานแบบตามลำดับอยู่แล้ว
การทำงานแบบ sequential คือ ทำงานบน main thread
ดัง code ตัวอย่าง

Parallel stream คืออะไร

เราสามารถแปลงจาก sequential มาเป็น parallel ได้เลย
โดยใช้งานผ่าน method parallelStream() หรือ parallel()
ซึ่งจะทำการแยก thread ไปทำงานตามแต่ละ core ของ CPU
และนำผลที่ได้มารวมกัน
ซึ่งใช้เทคนิคของ Fork and Join
ดัง code ตัวอย่าง

ลองมาทำ Benchmark ด้วย JMH (Java Microbenchmark Harness) กัน

ถึงแม้ว่าการทำงานแบบ parallel จะมีประโยชน์
แต่ก็มาพร้อมกับ overhead เช่นกัน
ทั้งการจัดการ thread (Fork and Join)
ทั้งการแยกและรวมข้อมูล
ทั้งการจัดการ memory

จะเลือกสิ่งใดต้องเข้าใจ รวมทั้งต้อง benchmark เสมอ