NiKoTron / dart-tags

ID3 Tag parser written on the pure dart language.
https://pub.dartlang.org/packages/dart_tags
MIT License
37 stars 16 forks source link

Speed #12

Closed o4x closed 4 years ago

o4x commented 4 years ago

Hi, this is really a good library but is very slow. Is there a way to speed it up?

NiKoTron commented 4 years ago

Hi @o4x, can you explain more detailed, what do you mean by slow? Any measurements or smth. else..

o4x commented 4 years ago

@NiKoTron when I use getTagFromByteArray in my project ui lagged and when use it on isolate take one or two seconds to return tags. its very much Can we do it faster?

NiKoTron commented 4 years ago

@o4x, Actually, I think we can. Currently, library looking through the whole file while scanning tags. Of course, It isn't a cheap operation and if you have a quite big file and slow IO. It's really may become a cause of slow parse. Well, I'll plan this for the next release.

Thank you for the helpful feedback!

NiKoTron commented 4 years ago

@o4x, Well I've rechecked it. The feature is that the file is reading only in the tag area has already been implemented.

I did some benchmarks and, It looks like bottleneck is file.readAsBytes(), cuz for parsing via getTagFromByteArray we must have a complete byte array of a file in the RAM.

Can you tell me what file do you parse (size and which tags) and on what's hardware do you you use (especially which kind of hard\solid state drive)?

So, I'll implement API that will accept the stream as an argument.

o4x commented 4 years ago

@NiKoTron I'm sorry I wasn't here for a while, I use profile mode in flutter and test it on my real phone . Its specifications are as follows:

Memory Storage System on chip
4 GB LPDDR4X RAM 64 GB UFS 2.1 Snapdragon 835

And the size of my songs is about 10 Mb .

for example this song

output

I/flutter ( 3706): album: 慒楤慫�
I/flutter ( 3706): artist: 䅀捲楨敶也橡晡�
I/flutter ( 3706): genre: 汆浡湥潣
I/flutter ( 3706): title: 汁桥
I/flutter ( 3706): track: 㔰ㄯ�
I/flutter ( 3706): year: 〲㜱
I/flutter ( 3706): comment: {language:eng, description:, body:
I/flutter ( 3706): lyrics: 湥ァ￾䃾牁档癩彥慎慪楦਍دنیا⠠䜆 درکㄠ䄆⨆ و⼠䜆 بی㌠ㄆ و㌠✆䔆✆䘆 شد㌠䜆䔆 من䠠 تو✠㈆ آن찠꤆ سفره찠 بی䘠✆䘆 شد਍از蘠㐆䔆 کبو倠⼆ ما†هی✠㐆꤆ بهㄠ✆䜆 افتاد✠匆䘆䈆⼆ㄆ که⠠✆ㄆ찆⼆찆䔆 تبدیل⠠䜆 باران㐠⼆ആ䜊ㄆ دوستꤠ䜆 با䔠✆ بود⼠㐆䔆䘆 شد䠠 خنجر㈠⼆ با䈠✆䄆䐆䜆 پیمان⠠㌆⨆ همꤠ✆㌆䜆 ِی⼠㈆⼆✆䘆 شد਍پ㐠 ِت䜠䔆䜆 ِی⼠ رها⼠찆䠆✆ㄆ کشیدند䠠 هی㌠䈆䄆 فرو縠✆㐆찆⼆ هی縠䘆Ⰶㄆ䜆 سیمان㐠⼆ആ䜊찆 شهد䠠 شکر⼠✆⼆䘆⼆℆䜠찆 سکه찠 زر⼠✆⼆䘆⼆℆✠匆ㄆ✆䔆 بسا倠㜆 شعر⨠⠆⼆찆䐆 به⼠꤆✆䘆 شد਍هرꤠ㌆ که⼠䐆㐆 میخواست䘠찆㈆䜆 به㈠䔆찆䘆 کوبید䜠찆 کشت䠠 تجاوزꤠㄆ⼆ تا�
I/flutter ( 3706): picture: {mime:image/jpeg, description:, bitmap: /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAPoA+gDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwCjZ/PNBCv9/wD1j/5/76raf5EeOOdE3zb33/xr/wABqrDc/ufLZPPdX/c/7a7furtqPTblbl0Vv3flP8n991/utX1Z+dEjzSPvaZN6fM6f30bd8tFhbXSTI0kHkIqbHj8tf33+zTkfZDPJJB

And as you can see in the example, Persian language is not supported either.

o4x commented 4 years ago

In version 0.2.3, the Persian language works well.

Nailik commented 4 years ago

The problem i found is (for me) in id3v2.dart There the end of the information get's recognized by end = offset < size; (line 73). This is really a problem as it will scan every bytes of the song for header information including just the sound. So i changed it a little bit, when the first tag result m is null i set end = false so it will stop after last tag is read. This should not make any problems as the song tags should not have empty tags in between. This is the commit in my fork: https://github.com/NiKoTron/dart-tags/commit/aa1f7777246b72c5e1d401354eee3cee2b6e34d6

n3rfd commented 4 years ago

Thanks @Nailik this is a life saver!

To give a little more context, before adding the fix, parsing 100 mp3 files of around 80mb in total took 500+ seconds to complete and from time to time crashes my app. After the fix, it only took ~15 seconds to extract all the tags from the same number of mp3 files!

NiKoTron commented 4 years ago

hi @o4x, @n3rfd ! this issue should be solved in the latest version (0.3.0) could you please check it?

o4x commented 4 years ago

Thank's @NiKoTron, yeah it's solved.

neilweber commented 3 years ago

@o4x, Well I've rechecked it. The feature is that the file is reading only in the tag area has already been implemented.

I did some benchmarks and, It looks like bottleneck is file.readAsBytes(), cuz for parsing via getTagFromByteArray we must have a complete byte array of a file in the RAM.

Can you tell me what file do you parse (size and which tags) and on what's hardware do you you use (especially which kind of hard\solid state drive)?

So, I'll implement API that will accept the stream as an argument.

Is accepting a stream as an argument still planned?