ภาษาโปรแกรมการทำงานมีโอกาสมากขึ้นในการรวบรวมการปรับเวลาให้เหมาะสมหรือไม่


10

ฉันกำลังอ่านหนังสือ "ฟังก์ชั่นการเขียนโปรแกรมสำหรับโลกแห่งความจริง" มันเริ่มต้นด้วยการเปรียบเทียบระหว่างภาษาการเขียนโปรแกรมที่จำเป็นและใช้งานได้ และมันระบุว่า 'ค่า' และ 'นิพจน์' ในการโปรแกรมเชิงฟังก์ชันนั้นแตกต่างจาก 'ตัวแปร' และ 'หน้าที่' ของการเขียนโปรแกรมที่จำเป็น จากการอภิปรายฉันได้เรียงลำดับความคิดที่พัฒนาขึ้น -

ฟังก์ชั่นการเขียนโปรแกรมภาษามีโอกาสมากขึ้นในการรวบรวมการเพิ่มประสิทธิภาพเวลากว่าคู่ที่จำเป็นของพวกเขา

จริงป้ะ?

คำตอบ:


16

ฟังก์ชั่นการเขียนโปรแกรมภาษาทำเพิ่มประสิทธิภาพการรวบรวมเวลามากขึ้น หนึ่งในเหตุผลคือความบริสุทธิ์ - การเกิดพร้อมกันนั้นเป็นเรื่องเล็กน้อยเพราะไม่มีรัฐ ดังนั้นคอมไพเลอร์สามารถใช้สองสาขาและเชื่อมโยงกันได้อย่างง่ายดายโดยไม่ต้องเปลี่ยนพฤติกรรมของโปรแกรม

ในเวลาเดียวกันสิ่งใดก็ตามที่สามารถคำนวณได้โดยไม่มีสถานะ (เช่นสิ่งใดที่ไม่ใช่ monadic ใน haskell) สามารถคำนวณล่วงหน้าได้โดยคอมไพเลอร์ แต่การคำนวณดังกล่าวอาจมีราคาแพงและอาจทำได้เพียงบางส่วนเท่านั้น

นอกจากนี้สิ่งที่ไม่จำเป็นต้องใช้การคำนวณสามารถเพิ่มประสิทธิภาพอย่างสมบูรณ์จากโปรแกรม


1
+1: การเขียนโปรแกรมฟรีผลข้างเคียงเป็นเรื่องง่ายมากที่จะเพิ่มประสิทธิภาพ
S.Lott

@ เรื่องทางคณิตศาสตร์: อันที่จริงการขนาน (ใน Haskell) เกิดขึ้นที่รวบรวมเวลาและเวลาทำงาน รวบรวมเวลาตัดสินใจหรือไม่ว่ามันคุ้มค่าในการสร้างชิ้นส่วน (เมล็ดด้าย) และเวลาทำงานกระบวนการเศษเท่าที่จะสามารถขึ้นอยู่กับจำนวนของหัวข้อที่คุณระบุ หากคุณระบุเพียงเธรดเดียวจะได้เศษที่สร้างขึ้น แต่จะถูกประมวลผลทีละเธรด
Matthieu M.

2
@ คณิตศาสตร์: การใช้ความบริสุทธิ์อีกครั้ง -> ความเกียจคร้านและการขาดการคำนวณ หากคุณสามารถพิสูจน์ได้ว่าไม่จำเป็นต้องใช้ค่าให้ตัดการคำนวณออกทั้งหมด ถ้ามันอาจจำเป็นต้องใช้ thunk ขี้เกียจ หากคุณรู้ว่าจำเป็นต้องใช้ให้คำนวณล่วงหน้า (เพื่อหลีกเลี่ยงค่าโสหุ้ยขี้เกียจ) ความบริสุทธิ์เป็นเรื่องที่น่าอัศจรรย์ :)
Matthieu M.

@Matthieu จุดดี
ทางเลือก

1
@Masse แม้แต่ IO monad ก็บริสุทธิ์ เพียงว่าผลลัพธ์ของ "การทำงาน" IO monad ไม่ใช่
ทางเลือก

7

โดยหลักการแล้วมีความเป็นไปได้ในการปรับเวลาให้เหมาะสมที่สุดสำหรับภาษาที่ใช้งานได้ดีกว่าภาษาที่จำเป็น

ที่น่าสนใจกว่าคือถ้าพวกมันถูกนำไปใช้จริงในคอมไพเลอร์ปัจจุบันและความเกี่ยวข้องของการปรับแต่งเหล่านี้ในทางปฏิบัติ (เช่นประสิทธิภาพสุดท้ายของรหัส 'ชีวิตจริง (TM)' ของ idiomatic ในสภาพแวดล้อมการผลิตด้วยการตั้งค่าคอมไพเลอร์

เช่นการส่ง Haskell สำหรับเกมมาตรฐานภาษาคอมพิวเตอร์ที่น่าอับอาย(ไม่ดีเท่าที่ควร - แต่มันไม่เหมือนว่ามี - ในขณะนี้ - มีอะไรที่ดีกว่ามากในที่นั้น) ให้ความรู้สึกว่ามีการใช้เวลาเป็นจำนวนมาก การปรับให้เหมาะสมด้วยตนเองซึ่งเผชิญหน้ากับการอ้างสิทธิ์เกี่ยวกับ "การเพิ่มประสิทธิภาพคอมไพเลอร์ที่เป็นไปได้เนื่องจากinsert some property about FP languages here" ทำให้ดูเหมือนว่าการปรับให้เหมาะสมที่สุด (ในปัจจุบันอย่างน้อย) มีความเป็นไปได้ทางทฤษฎีมากกว่าความเป็นจริงที่เกี่ยวข้อง

ฉันยินดีที่จะพิสูจน์ว่าผิดในจุดนี้


1
เหตุผลสำหรับการปรับแต่งแบบแมนนวลใน Haskell มีส่วนเกี่ยวข้องกับข้อเท็จจริงที่ว่าการดำเนินการ "ตรงไปตรง" บางอย่างใช้เวลาค่อนข้างนาน (จากมุมมองที่ซับซ้อน) ใน Haskell ตัวอย่างเช่นสมมติว่าคุณต้องการรับองค์ประกอบสุดท้ายของรายการ ใน Java นั่นเป็นการดำเนินการที่ค่อนข้างง่าย ใน Haskell วิธีnaïveต้องการให้คุณเดินรายการทั้งหมดจนกว่าคุณจะถึงจุดจบ (เนื่องจากลักษณะที่ขี้เกียจของรายการ) ทำให้เป็นการดำเนินการ O (n) นั่นคือ (ส่วนหนึ่ง) ที่การเพิ่มประสิทธิภาพด้วยตนเองเข้ามา
mipadi

2
ฉันแน่ใจว่ามีเหตุผลที่ถูกต้องสำหรับการเพิ่มประสิทธิภาพการรีดด้วยมือของ Haskell แต่สิ่งเหล่านี้จำเป็นสำหรับการดำเนินการ "ตรงไปตรงมา" ทำให้เกิดการแสดงผลว่าโอกาสที่มากขึ้นสำหรับการปรับรหัสให้เหมาะสมที่สุด
Alexander Battisti

6
มันมีความแตกต่างระหว่างอัลกอริธึมการออปติไมซ์และการออปติไมซ์โค้ดที่สร้างขึ้น ยกตัวอย่าง C: ถ้าฉันกำลังเขียนอัลกอริทึมการค้นหาฉันสามารถเขียนอัลกอริทึมไร้เดียงสาที่สามารถเดินผ่านรายการหรือใช้การค้นหาแบบไบนารี ในทั้งสองกรณีคอมไพเลอร์จะปรับรหัสของฉันให้เหมาะสม แต่จะไม่เปลี่ยนอัลกอริทึมการค้นหาไร้เดียงสาเป็นการค้นหาแบบไบนารี การปรับแต่งด้วยตนเองจำนวนมากในรหัส Haskell มีส่วนเกี่ยวข้องกับการปรับแต่งอัลกอริธึมเองมากกว่าการปรับรหัสที่สร้างให้เหมาะสม
mipadi

2
@mipadi แต่ดูเหมือนว่าอัลกอริทึมของ Haskell รุ่นตรงไปตรงมานั้นไม่ดีเท่าอัลกอริธึมของภาษาอื่นที่ตรงไปตรงมา (ฉันสงสัยว่าเกิดจากความไม่ตรงกันระหว่างแบบจำลองการทำงานและสถาปัตยกรรมคอมพิวเตอร์) แม้ว่ามันจะสร้างโค้ดได้ดี แต่ก็ยังไม่เพียงพอที่จะแก้ไขปัญหานี้ได้
Winston Ewert

>> ไม่ดีเท่าที่ควร << - คุณรู้ไหมว่ามันแย่หรือเปล่า? คุณหมายถึงอะไรด้วยการแนะนำว่า "ไม่ดี"? กรุณาระบุ
igouy

2

ในลักษณะการทำงานการไหลของค่าผ่านทางโปรแกรมเป็นอย่างมากมองเห็นได้มาก (ทั้งคอมไพเลอร์และโปรแกรมเมอร์) สิ่งนี้ทำให้ผู้รวบรวมจำนวนมากใช้เวลามากในการตัดสินใจว่าจะเก็บค่าไว้นานแค่ไหนที่จะเก็บมันไว้นาน ๆ

ในภาษาที่จำเป็นคอมไพเลอร์สัญญากับโปรแกรมเมอร์ว่าแบบจำลองที่ตัวแปรส่วนใหญ่สอดคล้องกับตำแหน่งจริงในหน่วยความจำซึ่งอยู่รอบ ๆ ตลอดอายุการใช้งานที่กำหนด อาจเป็นไปได้ว่าข้อความใด ๆ อาจอ่านจาก (หรือเขียนถึง!) ที่ตั้งใด ๆ เหล่านี้ดังนั้นคอมไพเลอร์สามารถแทนที่ตำแหน่งหน่วยความจำด้วยการจัดสรรการลงทะเบียนผสานสองตัวแปรเข้าในที่เก็บข้อมูลเดียวหรือทำการปรับให้เหมาะสมคล้ายกัน อื่นในโปรแกรมที่อาจมีการอ้างอิงตัวแปร

ตอนนี้มีสองประการ:

  • ชุมชนการเขียนโปรแกรมภาษามีการใช้จ่าย (เสีย? บริการ) จำนวนมากของความพยายามในช่วงห้าสิบปีในการพัฒนาวิธีที่ฉลาดที่จะทำการวิเคราะห์นี้ มีเทคนิคที่รู้จักกันดีเช่นการลงทะเบียนระบายสีและอื่น ๆ เพื่อให้ได้กรณีที่ง่ายขึ้นเกือบตลอดเวลา แต่สิ่งนี้เหมาะสำหรับคอมไพเลอร์ตัวใหญ่ตัวช้าและความซับซ้อนในการรวบรวมเพื่อให้ได้โค้ดที่มีคุณภาพ
  • ในขณะเดียวกันภาษาโปรแกรมที่ใช้งานได้ส่วนใหญ่ก็ไม่สามารถใช้งานได้อย่างแท้จริง จำนวนมากของโปรแกรมสิ่งที่จริงต้องทำเช่นตอบสนองต่อ I / O เป็นอย่างโดยเนื้อแท้ไม่ทำงานจึงไม่มีคอมไพเลอร์ได้อย่างสมบูรณ์ฟรีของเทคนิคเหล่านี้และไม่มีภาษาหลีกเลี่ยงพวกเขาทั้งหมด - แม้ Haskell ซึ่งเป็นบิตเกินไปบริสุทธิ์สำหรับรสนิยมของฉัน (การสะสมไมล์ของคุณอาจแตกต่างกัน) สามารถควบคุมและตัดส่วนที่ไม่ทำงานของรหัสของคุณเท่านั้น

แต่เพื่อตอบคำถามทั่วไปใช่กระบวนทัศน์การทำงานให้คอมไพเลอร์มีอิสระมากมายในการปรับให้เหมาะสมว่ามันไม่ได้มีการตั้งค่าที่จำเป็น


ทุกสิ่งทุกอย่างใน Haskell นั้นใช้งานได้มันเป็นเพียงแค่mainฟังก์ชั่นการเปลี่ยนสถานะของคุณแทนที่จะเป็นสิ่งที่ใช้สถานะของตัวเอง
ทางเลือก

ใช่และไม่ใช่ - แนวคิดมันค่อนข้างถูกต้องที่จะบอกว่าโปรแกรม Haskell เป็นฟังก์ชั่นที่บริสุทธิ์เหนือการโต้ตอบของผู้ใช้กับโปรแกรมนั้น (และสถานะของตัวสร้างตัวเลขสุ่มของระบบและเวลาแฝงของเครือข่ายในปัจจุบันและอื่น ๆ โดยเนื้อแท้ อินพุตที่ไม่ใช้งานได้โปรแกรมจะตอบสนองต่อ) แต่ในทางปฏิบัติมันเป็นความแตกต่างที่ไม่มีความแตกต่าง
jimwise

@ jimwise Referential transparent นั้นแตกต่างกันมาก
ทางเลือก

อย่างน้อยก็สำหรับวัตถุประสงค์ที่กล่าวถึงที่นี่ จุดของการดำเนินการเช่น IO หรือการสร้างตัวเลขสุ่มก็คือพวกเขาควรจะคืนค่าที่แตกต่างกันในแต่ละครั้งที่พวกเขาถูกเรียกด้วยอินพุตเดียวกันและสิ่งนี้ จำกัด การให้เหตุผลเกี่ยวกับพวกเขาอย่างเป็นธรรมชาติสำหรับโปรแกรมเมอร์หรือคอมไพเลอร์
jimwise

1
@ คณิตศาสตร์ใช่แน่นอนคุณสามารถดูแนวคิดแบบสุ่มหรืออินพุตของผู้ใช้ (หรือเวลาแฝงเครือข่ายหรือโหลดระบบ) เป็นสตรีมไม่สิ้นสุดหรือฟังก์ชั่นจากรัฐหนึ่งไปยังอีกรัฐหนึ่ง แต่ไม่ใช่มุมมองที่ให้เหตุผลที่เป็นประโยชน์ คุณหรือผู้เรียบเรียงของคุณ - Bob Harper ครอบคลุมเรื่องนี้ได้ดีใน โพสต์เมื่อเร็ว ๆ นี้ในบล็อกของเขาเกี่ยวกับหลักสูตร CS CSU การเขียนโปรแกรมฟังก์ชั่นใหม่ของ CMU
jimwise
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.