ทำในสองลูป

Dec 30 2022
จากพื้นฐานวิทยาการคอมพิวเตอร์ ฉันสงสัยว่าคำว่า 'ประสิทธิภาพ' จะต้องเป็นส่วนหนึ่งของสมองของฉันที่ไหนสักแห่งอยู่แล้ว ต้นไม้ทั้งหมดที่ฉันสำรวจ Os ขนาดใหญ่และโอเมก้าอยู่ที่นั่นเพื่อช่วยให้ฉันใช้แนวทางที่มีประสิทธิภาพมากขึ้น
ข้อความแจ้งการแพร่กระจายที่เสถียร: การ์ตูนมินิมอลของสองวงที่มีสีเรียบและสี่เหลี่ยมที่กระจัดกระจายแบบสุ่ม

จากพื้นฐานวิทยาการคอมพิวเตอร์ ฉันสงสัยว่าคำว่า 'ประสิทธิภาพ' จะต้องเป็นส่วนหนึ่งของสมองของฉันที่ไหนสักแห่งอยู่แล้ว ต้นไม้ทั้งหมดที่ฉันสำรวจ Os ขนาดใหญ่และโอเมก้าอยู่ที่นั่นเพื่อช่วยให้ฉันใช้แนวทางที่มีประสิทธิภาพมากขึ้น และใช่ — บางครั้งพวกเขาก็มีประโยชน์ และฉันภูมิใจในคำถาม CP ที่ฉันสามารถแก้ไขได้ หากคุณพบว่าตัวเองอยู่ในแวดวงวิศวกรรมผลิตภัณฑ์เหมือนฉัน บางทีคุณอาจจะแบ่งปันข้อมูลเชิงลึกของฉันว่าแนวคิดเรื่องประสิทธิภาพในวิศวกรรมผลิตภัณฑ์ไม่ใช่แนวคิดที่เราเรียนในวิทยาลัย ฉันตกลงกับความแตกต่างนี้แล้ว ท้ายที่สุดแล้ว ครูใหญ่โรงเรียนประถมของฉันก็สำเร็จการศึกษาระดับวิศวกรรมการบินและอวกาศและใช้ประโยชน์จากมันได้ดีที่สุด

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

โค้ดส่วนหนึ่งจะคำนวณเกรดเฉลี่ยของนักเรียนกลุ่มหนึ่งในหลายภาคการศึกษา จากนั้นส่งคืนแฮชแมปที่มีรหัสนักเรียนเป็นคีย์:

avgFinalGradesByStudent := make(map[studentID]float)
for _, student := range students {
  totalFinalGrades := 0.0
  for _, semester := range semesters {
    studentGrade := gradesRepository.getByStudentID(student.ID, semester) // fetch from db
    totalFinalGrades = totalFinalGrades + studentGrade.FinalGrade
  }
  avgFinalGradesByStudent[student.ID] := totalFinalGrades / len(semesters)
}

return avgFinalGradesByStudent

studentGrades := make(map[studentID][]float)
for _, student := range students {
  for _, semester := range semesters {
    semesterGrade := gradesRepository.getByStudentID(student.ID, semester) // fetch from db
    studentGrades[student.ID] = append(studentGrades[student.ID], semesterGrade)
  }
}

avgFinalGradesByStudent := make(map[studentID]int)
for _, student := range students {
  totalFinalGrades := 0
  for _, grade := range studentGrades[studentID] {
    totalFinalGrades += grade
  }
  avgFinalGradesByStudent[student.ID] := totalFinalGrades / len(semesters)
}

return avgFinalGradesByStudent

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

studentGrades := getStudentGradesForAllSemesters(students, semesters)
avgFinalGradesByStudent := calculateAverageFinalGrades(studentGrades)

return avgFinalGradesByStudent

// arrange
studentGrades := map[studentID][]int { 1: []int {97, 86, 51}, 2: []int {60, 85, 95} } 
// act
result := calculateAverageFinalGrades(studentGrades)
// assert
assert.Equal(78,result[1])
assert.Equal(80, result[2])

avgFinalGradesByStudent := make(map[studentID]float)
// container for the final results
topThreeGradesByStudent := make(map[studentID][]int)
for _, student := range students {
  totalFinalGrades := 0.0
  var topThreeGrades []int
  for _, semester := range semesters {
    studentGrade := gradesRepository.getByStudentID(student.ID, semester) // fetch from db
    totalFinalGrades = totalFinalGrades + studentGrade.FinalGrade
    // some code to figure out if this grade is the top three grades or not 
    // and add/remove from topThreeGrades
    // ...
  }
  avgFinalGradesByStudent[student.ID] := totalFinalGrades / len(semesters)
  topThreeGradesByStudent[student.ID] := topThreeGrades
}

return avgFinalGradesByStudent, topThreeGradesByStudent

studentGrades := getStudentGradesForAllSemesters(students, semesters)
avgFinalGradesByStudent := calculateAverageFinalGrades(studentGrades)
topThreeGradesByStudent := getTopThreeGradesByStudent(studentGrades)

return avgFinalGradesByStudent, topThreeGradesByStudent

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

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

สำหรับคุณ — คุณเคยเจอการวนลูปแบบ do-it-all-in-one-go แบบนี้มาก่อนหรือไม่? บางทีคุณอาจจะพบว่ามันสบายดี? ขอหารือ :)