Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

อย่าใจร้าย:ค่าเฉลี่ยทางสถิติและเปอร์เซ็นไทล์101

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

ค่าเฉลี่ย

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

ใน Ruby นี่คือสิ่งที่คำนวณเวลาตอบสนองเฉลี่ย:

def mean(array)
 (array.sum.to_f / array.length).round(2)
end
 
durations = [1,2,3,4,5,6,7,8,9,0]
mean(durations) #=> 4.5

หมายเหตุ :ในตัวอย่าง เพื่อผลลัพธ์ที่แม่นยำยิ่งขึ้นเมื่อทำการหาร เราแปลงค่าระยะเวลารวมเป็นโฟลต มิฉะนั้น Ruby จะปัดเศษลงเป็นจำนวนเต็มที่ใกล้ที่สุดโดยส่งคืน 4 แทน

ค่ามัธยฐาน

สถิติที่มีประโยชน์อีกอย่างหนึ่งคือค่ามัธยฐาน แม้ว่าจะฟังดูคล้ายกัน แต่ก็มีความแตกต่างระหว่างค่ากลางและค่ามัธยฐานของคอลเล็กชันของค่า

ค่ามัธยฐานคือค่าที่แยกครึ่งบนของเซตออกจากครึ่งล่างของเซต

สำหรับชุดข้อมูลที่มีค่าเป็นจำนวนคี่ คุณจะได้ค่ามัธยฐานโดยการจัดเรียงค่าก่อน แล้วจึงเลือกตัวเลขตรงกลาง สำหรับชุดที่มีค่าจำนวนคู่ หลังจากจัดเรียงแล้ว ค่ามัธยฐานจะเป็นค่าเฉลี่ยของตัวเลขตรงกลางสองตัว

def median(array)
  sorted_array = array.sort
  length = sorted_array.length
 
  if length.odd? # Middle number for odd arrays
    sorted_array[length / 2]
  else # Mean of two middle numbers
    first_value = sorted_array[length / 2]
    second_value = sorted_array[length / 2 - 1]
    (first_value + second_value) / 2.to_f
  end
end
 
# Even array
durations = [1,2,3,4,5,6,7,8,9,0]
median(durations) #=> 4.5
 
# Odd array
durations = [1,1,2,3,4,5,6,7,8,9,0]
median(durations) #=> 4

สถิตินี้เป็นวิธีที่ดีในการดูว่าข้อมูลเบ้มากหรือหางยาว

durations = [1,2,3,4,5,2000]
 
median(durations) #=> 3.5
mean(durations) #=> 335.83

ค่าเฉลี่ยสำหรับระยะเวลาข้างต้นจะเป็น 335.83 เนื่องจากมีค่าผิดปกติเพียง 2000ms ค่ามัธยฐานซึ่งก็คือ 3.5 . เท่านั้น , แสดงว่ามีความเบ้

เมื่อคำนวณทั้งค่าเฉลี่ยและค่ามัธยฐานของชุดข้อมูล คุณจะทราบได้ว่ามีค่าผิดปกติขนาดใหญ่หรือส่วนท้ายยาว

ปัญหาเกี่ยวกับค่าเฉลี่ย

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

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

ตัวอย่างเช่น กำหนดระยะเวลาต่อไปนี้ซึ่งมีลูกค้า 10 รายร้องขอหน้าเว็บที่มีระยะเวลาระหว่าง 100 มิลลิวินาทีถึง 1 วินาที

[100,100,100,100,100,100,100,100,100,1_000]

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

ตัวอย่างข้างต้นมีไว้สำหรับ 10 คำขอเท่านั้น แต่ลองนึกภาพถ้าคุณมีคำขอนับพันต่อวัน นั่นหมายความว่าผู้ใช้หลายร้อยคนมีประสบการณ์ที่แย่มาก

เปอร์เซ็นไทล์

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

ให้ชุด (เรียง) ต่อไปนี้:

[100,100,200,200,300,300,400,400,500,5_000]

หากเราต้องการทราบเปอร์เซ็นต์ไทล์ที่ 20 เราสามารถคำนวณได้ดังนี้:มี 10 ค่าในชุด ค่าที่ต้องการอยู่ที่ตำแหน่ง 1 (20.0 / 100 * 10 - 1 ) เนื่องจากอาร์เรย์ของเราเริ่มต้นที่ศูนย์ เนื่องจากอาร์เรย์นี้มีจำนวนรายการเท่ากัน เราจึงต้องคำนวณค่าเฉลี่ยระหว่างดัชนี (2 ) และดัชนี + 1 (3 ). ซึ่งจะส่งผลให้มีค่า 150 สำหรับเปอร์เซ็นไทล์ที่ 20

การใช้งาน Ruby ที่ไร้เดียงสามากจะมีลักษณะดังนี้:

def percentile(array, wanted_percentile)
  sorted_array = array.sort
 
  index = (wanted_percentile.to_f / 100) * sorted_array.length - 1
 
  # Check if index is not a round number
  if index != index.to_i
    sorted_array.at(index.ceil)
  elsif sorted_array.length.even?
    first_value = sorted_array.at(index)
    second_value = sorted_array.at(index + 1)
    (first_value + second_value) / 2
  else
    sorted_array.at(index)
  end
end
 
# An array with an odd amount of numbers
durations = [100,200,200,300,300,400,400,500,5_000]
 
percentile(durations, 20) #=> 100
percentile(durations, 90) #=> 500
percentile(durations, 95) #=> 5000, index is a fraction, 9.5 the rounded index is 10
 
# An array with an even amount of numbers
durations = [100,100,200,200,300,300,400,400,500,5_000]
 
percentile(durations, 20) #=> 150, average of index 1 & 2 `(100 + 200) / 2`
percentile(durations, 90) #=> 2750, average of index 8 & 9 `(500 + 5000) / 2
percentile(durations, 95) #=> 500, index is a fraction, 8.55 the index is 9

percentileนี้ ฟังก์ชันดูคล้ายกับmedian .ของเรามาก การคำนวณและในความเป็นจริง median เหมือนกับ 50th เปอร์เซ็นต์ไทล์

durations = [1,2,3]
 
percentile(durations, 50) == median(durations) #=> true

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

สิ่งแปลกประหลาด

เนื่องจากวิธีคำนวณเปอร์เซ็นไทล์และค่าเฉลี่ย บางครั้งจึงเป็นไปได้ที่ค่าเปอร์เซ็นไทล์ที่ 90 ลดลงต่ำกว่าค่าเฉลี่ย ตัวอย่างเช่น จากชุดข้อมูลต่อไปนี้:

durations = [1,1,1,1,1,1,1,1,1,1,2000]
 
percentile(durations, 90) #=> 1
mean(durations) #=> 182.73

นี่จะทำให้เรา mean จาก 182.73 และเปอร์เซ็นไทล์ที่ 90 เพียง 1 .

หากระบบรวบรวมเมตริกของคุณแสดงเฉพาะเปอร์เซ็นไทล์ที่ 90 และค่าเฉลี่ย คุณยังสามารถสรุปได้ว่ามีค่าผิดปกติขนาดใหญ่อยู่ที่ไหนสักแห่งในชุดข้อมูลของคุณหากเปอร์เซ็นไทล์ที่ 90 ลดลงต่ำกว่าค่าเฉลี่ย

👋 หากคุณชอบบทความนี้ ยังมีอีกมากที่เราเขียนเกี่ยวกับประสิทธิภาพของ Ruby (on Rails) โปรดดูรายการตรวจสอบประสิทธิภาพ Ruby ของเรา

คุณเกือบ 100% ของโพสต์นี้

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