วิธีที่มีประสิทธิภาพที่สุดในการจัดเก็บข้อมูลนี้คืออะไร?


9

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

ผู้ใช้ต้องเลือกผู้ผลิตยี่ห้อรุ่นและสีของรถใน GUI ฉันมีไฟล์ข้อความขนาดใหญ่ที่มีหน้าตาดังนี้:

Ford Truck F150 red
Ford Truck F150 blue
Ford Truck F150 black
Ford Truck F150 silver
Ford Truck F250 red
Ford Truck F250 green
Ford Sedan Taurus red
Ford Sedan Taurus green
Ford Sedan Taurus white
Ford...
...

Subaru SUV Forester blue
Subaru SUV Forester red
Subaru SUV Outback Black
Subaru SUV Outback Green
Subaru SUV Outback Blue
Subaru SUV Outback Red
Subaru...
...

etc.

ดังนั้นหากการเลือกแรกคือ Subaru กล่องที่สอง (ยี่ห้อ) ไม่ควรมีตัวเลือกในการเลือกรถบรรทุกเพราะไม่มี Subarus เป็นรถบรรทุก หากพวกเขาเลือกฟอร์ดซีดานและทอรัสกล่องสุดท้าย (สี) ไม่ควรแสดงตัวเลือกเพื่อเลือกสีน้ำเงิน หรือดำ หรือสิ่งอื่นใดนอกเหนือจากสีแดงสีเขียวหรือสีขาว

ผู้ที่เขียนโค้ดก่อนที่ฉันจะมาด้วยสิ่งนี้ (ใน python-y psuedocode):

def getValidOptions():
    items = []
    for i from 0 to numRows:
        options = getLine().split()
        if selectingManufacturer:
            if options[0] not in items:
                items.append(options[0])
        else if selectingMake:
            if selectedManufacturer == options[0] and options[1] not in items:
               items.append(options[1])
        else if selectingModel:
            if selectedManufacturer == options[0] and selectedMake == options[1] and options[2] not in items:
                items.append(options[2])
        else if selectingColor:
            if selectedManufacturer == options[0] and selectedMake == options[1] and selectedModel == options[2] and options[3] not in items:
                items.append(options[3])
    return items

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

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


2
ทำไมไม่ใช้ฐานข้อมูล
Tulains Córdova

คำตอบ:


6

คำตอบอื่น ๆ ทั้งหมดที่ฉันอ่านดูเหมือนจะไม่สนใจกฎพื้นฐานสองข้อของการพัฒนาซอฟต์แวร์:

  • ชี้แจงข้อกำหนดก่อน (โดยเฉพาะความต้องการด้านประสิทธิภาพและการจัดเก็บ)

  • ทำให้มันง่ายโง่ (ดูKISS )

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

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

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

# selectedOptions is a list, containing either nothing, or "selectedManufacturer"
# or [selectedManufacturer, selectedMake], ..., and so on
def getValidOptions(selectedOptions):
    items = []
    level = selectedOptions.size()
    for i from 0 to numRows:
        options = getLine().split()
        if selectedOptions == options[0:level-1] and options[level] not in item:
            items.append(options[level])
    return items

ดังนั้นนี่คืออัลกอริทึมเดียวกันโดยไม่มีรหัสซ้ำซ้ำอีก

เนื่องจากเป็นสิ่งที่ชัดเจนgetValidOptionsว่าต้องถูกเรียกมากกว่าหนึ่งครั้ง (อย่างน้อยหนึ่งครั้งต่อระดับ) ฉันแนะนำให้ใช้การเพิ่มประสิทธิภาพเพียงครั้งเดียว (หากนี่ไม่ใช่กรณี): ให้แน่ใจว่าgetLineฟังก์ชั่นดึงข้อมูลจากหน่วยความจำหลักและไม่ อ่านไฟล์จากดิสก์อีกครั้งและอีกครั้ง


คุณต้องการย้าย "level = selectedOptions.size ()" หน้า numRows วนซ้ำ
AI Breveleri

6

ข้อมูลที่คุณมีมีโครงสร้างคล้ายต้นไม้ซึ่งสำหรับผู้ผลิตแต่ละรายคุณมีต้นไม้จำลองและสำหรับแต่ละรุ่นคุณมีสี (และอื่น ๆ )

ดังนั้นคุณสามารถแยกกระบวนการของข้อมูลนี้ได้สองวิธี:

  1. หลังจากอัพเดตเป็นไฟล์ข้อความคุณต้องประมวลผลไฟล์ไฟล์นั้นและแปลงเป็นโครงสร้างแบบต้นไม้
  2. เมื่อโหลดแอปพลิเคชันคุณจะโหลดโครงสร้างต้นไม้เท่านั้น

โครงสร้างต้นไม้สามารถนำไปใช้กับสิ่งที่เรียกว่าhash , อาเรย์แบบเชื่อมโยงหรือพจนานุกรมในภาษาเช่น Java, PHP, Javascript หรือ Python ด้วยโครงสร้างนี้คุณมี:

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

ขึ้นอยู่กับภาษาการเขียนโปรแกรมของคุณสิ่งนี้สามารถใช้งานได้เร็วขึ้นหรือช้าลง ตัวอย่างเช่น:

  • C # : คุณสามารถใช้โครงสร้างแบบทรี1จากนั้นทำเครื่องหมายให้เป็นแบบอนุกรมได้
  • VB.Net : คุณสามารถสร้างโครงสร้างแบบต้นไม้ในแอปพลิเคชั่นเดียวและทำให้เป็นอนุกรมในไฟล์
    • สำหรับสิ่งนี้Runtime.Serialization.Formatters.Binary.BinaryFormatterอาจมีประโยชน์ แต่ฉันไม่มีความเชี่ยวชาญในการจัดลำดับด้วย VB.Net
  • Javascript : คุณสามารถสร้างโครงสร้างแบบต้นไม้ในไฟล์ JSON ซึ่งจะต้องโหลดทุกครั้งที่โหลดแอป
  • PHP : คุณสามารถสร้างโครงสร้างข้อมูลแบบต้นไม้ต่อเนื่องหรือคุณสามารถโหลด JSON ได้เช่นกัน
  • Java : คุณสามารถเป็นอันดับโครงสร้างข้อมูลที่สร้างที่ใช้อินเตอร์เฟซClassjava.io.Serializable

การอ้างอิง :

1: https://dvanderboom.wordpress.com/2008/03/15/treet-implementing-a-non-binary-tree-in-c/
- คำอธิบายที่สมบูรณ์เกี่ยวกับการใช้ต้นไม้ใน C #
- ค้นหาความคิดเห็นที่มีคนถามเกี่ยวกับการทำให้เป็นอันดับวัตถุนั้นและคำตอบสำหรับความคิดเห็นนั้น


1
ใช่ฉันคิดเกี่ยวกับการใช้ต้นไม้ แต่ฉันไม่รู้ว่ามันเป็นความคิดที่ดีที่สุดหรือไม่เพราะไม่มีโครงสร้างของต้นไม้ (ที่ฉันรู้) ใน C # และโครงการมีขนาดเล็กมากฉันไม่รู้ว่า มันจะคุ้มค่าที่จะใช้เวลามากในการtree with an arbitrary number of nodesดำเนินการ
James

ในตอนนี้ฉันยังไม่มีความเชี่ยวชาญใน C # แต่อย่างน้อยในภาษาอื่นเช่น Java และ PHP คุณสามารถมีพจนานุกรมบางประเภทซึ่งแต่ละคีย์สามารถมีค่าเป็นพจนานุกรมอื่นได้
Nicolás

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

3

วิธีง่ายๆในการเก็บข้อมูลคือการเก็บข้อมูลลงในฐานข้อมูล SQLite SQLite ไม่เหมือนกับฐานข้อมูล SQL ส่วนใหญ่เหมาะสำหรับใช้เป็นรูปแบบไฟล์แอปพลิเคชัน วิธีนี้มีประโยชน์หลายประการ:

  1. ไม่จำเป็นต้องเขียนรหัส serializer หรือ deserializer
  2. ไฟล์สามารถแก้ไขและสืบค้นได้โดยโปรแกรมที่มีอยู่มากมาย
  3. ความยุ่งเหยิงตามเงื่อนไขที่คุณพูดถึงในคำถามจะถูกหลีกเลี่ยง หากต้องการ จำกัด รายการแบบหล่นลงให้สร้างคำสั่งง่ายๆโดยให้ข้อใดข้อหนึ่งตรงกับแต่ละคอลัมน์ (เช่นselect distinct model where manufacturer='ford' and color = 'red')

สิ่งนี้บังคับให้คุณเรียนรู้ SQL แต่หลีกเลี่ยงความจำเป็นในการเรียนรู้รูปแบบไฟล์ที่กำหนดเอง


1

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

สำหรับการเข้าถึงที่รวดเร็วที่สุดให้จัดเก็บข้อมูลใน 6 ไฟล์โดยที่แต่ละไฟล์เป็นดัชนีในไฟล์ถัดไป

มีหลายวิธีในการสร้างดัชนีไฟล์ ฉันมักจะใช้ช่วงห้อย เมื่อผู้ใช้ทำการเลือกแต่ละรายการให้ใช้ช่วงเพื่อ จำกัด การอ่านไฟล์ถัดไป

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

แน่นอนว่าต้องเรียงไฟล์ ฉันนับเลขเพื่อประกอบการวาด หมายเลขบรรทัดไม่ควรปรากฏในไฟล์

--| file3.dat |--
 0 Ford Truck F150 red
 1 Ford Truck F150 blue
 2 Ford Truck F150 black
 3 Ford Truck F150 silver
 4 Ford Truck F250 red
 5 Ford Truck F250 green
 6 Ford Sedan Taurus red
 7 Ford Sedan Taurus green
 8 Ford Sedan Taurus white
 9 Subaru SUV Forester blue
10 Subaru SUV Forester red
11 Subaru SUV Outback Black
12 Subaru SUV Outback Green
13 Subaru SUV Outback Blue
14 Subaru SUV Outback Red

หากต้องการสร้างดัชนีแรกให้บันทึกสำหรับชุดค่าผสมแต่ละชุดของสามฟิลด์แรกในไฟล์ ในแต่ละระเบียนให้เก็บหมายเลขบรรทัดแรกและบรรทัดสุดท้ายที่ชุดค่าผสมนั้นปรากฏขึ้น

--| file2.dat |--
 0 Ford Truck F150       0   3
 1 Ford Truck F250       4   5
 2 Ford Sedan Taurus     6   8
 3 Subaru SUV Forester   9  10
 4 Subaru SUV Outback   11  14

ดัชนีที่สองสร้างขึ้นในลักษณะเดียวกันโดยใช้สองฟิลด์แรกของดัชนีแรก

--| file1.dat |--
 0 Ford Truck        0   1
 1 Ford Sedan        2   2
 2 Subaru SUV        3   4

และระดับที่สามระดับสูงสุดในกรณีนี้คือดัชนี

--| file0.dat |--
 0 Ford          0   1
 1 Subaru        2   2

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

คุณสามารถลดข้อกำหนดการจัดเก็บไฟล์เพิ่มเติมได้โดยกำจัดข้อมูลที่ซ้ำซ้อน

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

นอกจากนี้เนื่องจากคุณจะใช้เฉพาะฟิลด์สุดท้ายในแต่ละระเบียนเพื่อเติมรายการที่เลือกคุณไม่จำเป็นต้องเก็บฟิลด์อื่น

การเรนเดอร์ขั้นต่ำของดัชนีเรียงซ้อนจะมีลักษณะเช่นนี้โดยที่เห็บ 'หมายถึงหมายเลขที่ไม่ได้ถูกจัดเก็บจริงในไฟล์

--| file0.dat |--
 0' Ford         0'   1
 1' Subaru       2'   2

--| file1.dat |--
 0' Truck        0'   1
 1' Sedan        2'   2
 2' SUV          3'   4

--| file2.dat |--
 0' F150         0'   3
 1' F250         4'   5
 2' Taurus       6'   8
 3' Forester     9'  10
 4' Outback     11'  14

--| file3.dat |--
 0' red
 1' blue
 2' black
 3' silver
 4' red
 5' green
 6' red
 7' green
 8' white
 9' blue
10' red
11' Black
12' Green
13' Blue
14' Red

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

ตัวอย่าง:

file0.datคุณกรอกรายการเลือกครั้งแรกจากทั้งหมดของ (ฟอร์ด, Subaru)

ผู้ใช้เลือก "ฟอร์ด" ตัวห้อยที่สอดคล้องกันคือ 0 และ 1

คุณกรอกข้อมูลรายชื่อตัวเลือกที่สองจากสาย 0-1 file1.datของ (รถบรรทุก, ซีดาน)

ผู้ใช้เลือก "ซีดาน" ตัวห้อยที่สอดคล้องกันคือ 2 และ 2

อย่างที่คุณเห็นตามเวลาที่ผู้ใช้เลือกเช่น "ฟอร์ด" "ซีดาน" "ราศีพฤษภ" คุณจะพบว่าคุณต้องอ่านบรรทัดที่ 6 ถึง 8 จากfile3.datการกรอกรายการตัวเลือกที่สี่เท่านั้น

ฉันขอโทษสำหรับคำอธิบายที่ค่อนข้างยาว แต่มันก็สายเกินไปและฉันไม่มีเวลาเขียนสั้น ๆ

เพิ่ม: หากคิดเพิ่มเติมไฟล์สามารถต่อกันเป็นไฟล์เดียว

--| file.dat |--
 0' -            1'   2
 1' Ford         3'   4
 2' Subaru       5'   5
 3' Truck        6'   7
 4' Sedan        8'   8
 5' SUV          9'  10
 6' F150        11'  14
 7' F250        15'  16
 8' Taurus      17'  19
 9' Forester    20'  21
10' Outback     22'  25
11' red          -'   -
12' blue         -'   -
13' black        -'   -
14' silver       -'   -
15' red          -'   -
16' green        -'   -
17' red          -'   -
18' green        -'   -
19' white        -'   -
20' blue         -'   -
21' red          -'   -
22' Black        -'   -
23' Green        -'   -
24' Blue         -'   -
25' Red          -'   -

สิ่งนี้ถูกใช้เหมือนกับไฟล์หลาย ๆ เวอร์ชันยกเว้นว่าคุณต้องการบรรทัดแรกจำลองเพื่อให้มีช่วงตัวห้อยแรก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.