2011-11-07 15 views
5

के बीच न्यूलाइन गणना की गति की तुलना में मैं पढ़ने के लिए प्रदर्शन की तुलना कर रहा हूं कि कितनी पंक्तियों में फ़ाइल है।डब्ल्यूसी और स्मॉलटॉक

$ time wc -l bigFile.csv 
1673820 bigFile.csv 

real 0m0.157s 
user 0m0.124s 
sys  0m0.062s 

और फिर एक साफ Pharo कोर स्मालटाक नवीनतम 1,3

| file lineCount | 
Smalltalk garbageCollect. 
(Duration milliSeconds: [ file := FileStream readOnlyFileNamed: 'bigFile.csv'. 
lineCount := 0. 
[ file atEnd ] whileFalse: [ 
    file nextLine. 
    lineCount := lineCount + 1 ]. 
file close. 
lineCount. ] timeToRun) asSeconds. 
15 

मैं कैसे तेजी से होने की स्मालटाक कोड में तेजी लाने के कर सकते हैं में:

मैं यह पहली बार WC कमांड लाइन उपकरण का उपयोग किया था या डब्ल्यूसी प्रदर्शन से करीब?

उत्तर

8
[ (PipeableOSProcess waitForCommand: 'wc -l /path/to/bigfile2.csv') output ] timeToRun. 

ऊपर दी गई रिपोर्ट ~ 207 मिलीसेकेंड, जिसमें तत्कालीन सूचना:

real 0m0.160s 
user 0m0.131s 
sys  0m0.029s 

मैं मजाक कर रहा हूँ, लेकिन यह भी गंभीर। पहिया को फिर से शुरू करने की कोई ज़रूरत नहीं है। एफएफआई, ओएसप्रोसेस, जिंक, इत्यादि। यूनिक्स उपयोगिताओं जैसी चीजों का उपयोग करने के पर्याप्त अवसर प्रदान करते हैं जिन्हें दशकों से युद्ध-परीक्षण किया गया है।

अगर आपका प्रश्न स्मालटाक खुद के बारे में वास्तव में अधिक था, एक शुरुआत होगी:

  • ~ 10 सेकंड
  • बचाया धारा द्विआधारी बनाने:

    [ FileStream 
        readOnlyFileNamed: '/path/to/reallybigfile2.csv' 
        do: [ :file | | endings count | 
         count := 0. 
         file binary. 
         file contents do: [ :c | c = 10 ifTrue: [ count := count + 1 ] ]. 
         count ] 
    ] timeToRun. 
    

    कि 2.5 सेकंड के लिए नीचे आप मिल जाएगा

  • readOnlyFileNamed: कार्य करें: बचाया ~ 1 सेकंड
  • लाइन अंत खोजने मैन्युअल बजाय #nextLine बचाया ~ 4 सेकंड
  • का उपयोग कर

एक क्लीनर, लेकिन 1/2 दूसरा अब सेशन होगा:

file contents occurrencesOf: 10.

बेशक

, अगर बेहतर प्रदर्शन की जरूरत है, और आप FFI/OSProcess का उपयोग नहीं करना चाहते हैं, क्या तुम करोगी फिर एक प्लगइन लिखें।

+0

मुझे लगता है कि आपके कोड में सबसे बड़ी बचत फ़ाइल बाइनरी बनाने से नहीं आती है, लेकिन "सामग्री" का उपयोग करके प्रसंस्करण से पहले पूरी फ़ाइल को स्मृति में पढ़ने से। उचित आकार के टुकड़ों में फ़ाइल को पढ़ने के बारे में इसके बारे में किराया देना चाहिए। –

+0

मैंने दोबारा जांच की ... # बाइनरी वास्तव में 10 सेकंड बनाम #asciiValue को कॉल कर रहा है या "कैरेक्टर एलएफ" की तुलना में (यहां तक ​​कि अगर एक अस्थायी में कैश किया गया हो)। #contents ने # सेकंड के साथ एक मैनुअल लूप बनाम 3.5 सेकंड बचाया। –

1

आप स्मृति में पूरे फ़ाइल को पढ़ने खर्च कर सकते हैं, तो सबसे सरल कोड

[ FileStream 
    readOnlyFileNamed: '/path/to/reallybigfile2.csv' 
    do: [ :file | file contents lineCount ] 
] timeToRun. 

यह वामो (लिनक्स), सीआर (ओल्ड मैक), सीआर वामो (आप नाम के चिड़ियाघर संभाल लेंगे है यह)। सीन से कोड केवल उसी लागत के लिए एलएफ को संभालता है। मैं कहूंगा कि छोटे मूलभूत बनाम सी के लिए एक कारक 10 ऐसे बुनियादी परिचालनों के लिए अपेक्षित है, इसलिए मुझे संदेह है कि आप अपने खुद के प्राइमेटिव को जोड़ने के बिना अधिक दक्षता प्राप्त करते हैं।

संबंधित मुद्दे