timo-71

Рейтинг
63
Регистрация
19.09.2018
hakuna matata:
Sucked from the finger task and write a new solution, but all have been written for a long time there, and libs.

The theme should be treated as a warm-up, so it is interesting. Well, the exchange of views, for those who do not

hakuna matata:
I'm not a programmer

And so, now look:

hakuna matata:
They are fully in Google https://github.com/salsify/jsonstreamingparser

 "Require": { 
"Php": "^ 7.2",
"Twig / twig": "^ 2.0",
"Box / spout": "^ 3.0",
"Endroid / qr-code": "*",
"salsify / json-streaming-parser ": "*"
}

Vpendyurivaem

 header ( 'content-type: text / plain'); 
$ Testfile = '/ var / web / aio / data / json';
$ Listener = new \ JsonStreamingParser \ Listener \ InMemoryListener ();

logger ( 'Before JsonStreamingParser \\ Parser');
print_r (end ($ GLOBALS [ 'aapp_timing']));
$ Stream = fopen ($ testfile, 'r');
try {
$ Parser = new \ JsonStreamingParser \ Parser ($ stream, $ listener);
$ Parser-> parse ();
fclose ($ stream);
} Catch (Exception $ e) {
fclose ($ stream);
throw $ e;
}
logger ( 'After JsonStreamingParser \\ Parser' );
print_r (end ($ GLOBALS [ 'aapp_timing']));

var_dump ($ listener-> getJson ());

It does not make anything, ($ listener-> getJson () after the logger), just set up, but added 243.5660 (ms) and 4+ meters

 Array 
(
[Msg] => Before JsonStreamingParser \ Parser
[Afterstart] => 3.1090 (ms)
[Afterprevios] => 0.0880 (ms)
[Mem_peak] => 0.51 / 2.00 (mb)
)
Array
(
[Msg] => After JsonStreamingParser \ Parser
[Afterstart] => 246.6750 (ms)
[afterprevios] => 243.5660 (ms )
[Mem_peak] => 5.21 / 4.00 (mb)
)
array (10000) {
[0] =>
array (2) {
[ "Id"] =>
int (21675)
[ "Scores"] =>
float (0.27687288427211)

Code logger functions:

 function logger ($ message) 
{
if (_ DEBUG!) return 0;
if (! array_key_exists ( 'aapp_timing', $ GLOBALS)) {
$ GLOBALS [ 'aapp_timing'] = [];
$ Last = $ GLOBALS [ 'aapp_last_timing'] = _STIME;
} Else $ last = $ GLOBALS [ 'aapp_last_timing'];
$ T1 = microtime (true);
$ M = (memory_get_usage () / 1024) / 1024;
$ Mp = (memory_get_peak_usage (true) / 1024) / 1024;
$ M = sprintf ( "% 01.2f /% 01.2f (mb)", $ m, $ mp);
$ GLOBALS [ 'aapp_timing'] [] = [ 'Msg' => $ message,
'Afterstart' => __timer ($ t1, _STIME),
'Afterprevios' => __timer ($ t1, $ last),
'Mem_peak' => $ m
];
$ GLOBALS [ 'aapp_last_timing'] = $ t1;
}
png hakuna.png
danforth:
На пыхе кстати можно декодер через yield завернуть, возможно будет быстрее

Может, но что что то существенное генератором выиграем сомнительно. Тут ресурсов 0 да маленько (0.36/2 (memory_get_usage/memory_get_peak_usage)).

Где можно выиграть. По операциям:

На коленке за 10 мин 35 строк кода:


test
json_decode x 10000: 16.0880 ms

json_encode x 3000: 4.3969 ms

file_append [ (json x 10 x 00) ]: 5.7662 ms

file_append [ (json x 3000) ]: 55.0900 ms

Кроме читать блоками (где 50-60мс), потенциал, только в месте записи. Не 3000 раз file_put_contents($file, $dd, FILE_APPEND);

а, например 300, но 10 найденных разом. В первом варианте у меня записи не было, в во втором, который с посложнее jsonами пачками по 500 найденных

Я все таки сторонник того что, json надо раскодировать, поэтому 10000 раз разобрать придется. Это дает гибкость и универсальность.

$d = '

{
"id": 47704,
"scores": 0.7003193510956659
}';
$t0 = microtime(true);
for($i=0;$i<10000;$i++){
$j = json_decode($d);
}
echo sprintf("json_decode x 10000: %01.4f ms",
(microtime(true) - $t0) * 1000), "\n\n";

print_r($j);
$t0 = microtime(true);
for($i=0;$i<3000;$i++){
$s = json_encode($j);
}
echo sprintf("json_encode x 3000: %01.4f ms",
(microtime(true) - $t0) * 1000), "\n\n";

$dd = str_repeat ( $d , 10 );
$file = '/var/web/aio/data/json-22';
$t0 = microtime(true);
file_put_contents($file, '['); for($i=0;$i<300;$i++){
file_put_contents($file, $dd, FILE_APPEND);
}
file_put_contents($file, ']', FILE_APPEND);
echo sprintf("file_append [ (json x 10 x 00) ]: %01.4f ms",
(microtime(true) - $t0) * 1000), "\n\n";

$t0 = microtime(true);
file_put_contents($file, '['); for($i=0;$i<3000;$i++){
file_put_contents($file, $d, FILE_APPEND);
}
file_put_contents($file, ']', FILE_APPEND);
echo sprintf("file_append [ (json x 3000) ]: %01.4f ms",
(microtime(true) - $t0) * 1000), "\n\n";

exit();
Danforth:
On pyhe way you can wrap the decoder through the yield may be faster

Maybe, but that is a significant generator win dubious. There is little resources yes 0 (0.36 / 2 (memory_get_usage / memory_get_peak_usage)).

Where you can win. On operations:

At knee 10 min 35 lines of code:


test
json_decode x 10000: 16.0880 ms

json_encode x 3000: 4.3969 ms

file_append [(json x 10 x 00)]: 5.7662 ms

file_append [(json x 3000)]: 55.0900 ms

Also read blocks (where 50-60ms) potential only in the recording position. Not 3,000 times file_put_contents ($ file, $ dd, FILE_APPEND);

but, for example 300, but 10 found again. In the first case I have not been recording, in the second, which is more difficult to jsonami packs of 500 found

I still support the idea that, it is necessary to decode the json, so 10,000 times have to parse. This gives flexibility and versatility.

 $ D = ' 
{
"Id": 47704,
"Scores": 0.7003193510956659
} ';
$ T0 = microtime (true);
for ($ i = 0; $ i <10000; $ i ++) {
$ J = json_decode ($ d);
}
echo sprintf ( "json_decode x 10000:% 01.4f ms",
(Microtime (true) - $ t0) * 1000), "\ n \ n";

print_r ($ j);
$ T0 = microtime (true);
for ($ i = 0; $ i <3000; $ i ++) {
$ S = json_encode ($ j);
}
echo sprintf ( "json_encode x 3000:% 01.4f ms",
(Microtime (true) - $ t0) * 1000), "\ n \ n";

$ Dd = str_repeat ($ d, 10);
$ File = '/ var / web / aio / data / json-22';
$ T0 = microtime (true);
file_put_contents ($ file, '['); for ($ i = 0; $ i <300; $ i ++) {
file_put_contents ($ file, $ dd, FILE_APPEND);
}
file_put_contents ($ file, ']', FILE_APPEND);
echo sprintf ( "file_append [(json x 10 x 00)]:% 01.4f ms",
(Microtime (true) - $ t0) * 1000), "\ n \ n";

$ T0 = microtime (true);
file_put_contents ($ file, '['); for ($ i = 0; $ i <3000; $ i ++) {
file_put_contents ($ file, $ d, FILE_APPEND);
}
file_put_contents ($ file, ']', FILE_APPEND);
echo sprintf ( "file_append [(json x 3000)]:% 01.4f ms",
(Microtime (true) - $ t0) * 1000), "\ n \ n";

exit ();
DenisVS:
Надо какую-то обёртку, время всех запущеных разом скриптов (на разных языках) сравнивать.

С точки зрения научного эксперимента, методику сравнения может и имеет смысл продумать. А в данной теме смысла большого не вижу. danforth, выиграл с 5-10 кратным перевесом, но у него GO и судя по

func NewDecoder
func NewDecoder(r io.Reader) *Decoder
NewDecoder returns a new decoder that reads from r.
The decoder introduces its own buffering and may read data from r beyond the JSON values requested.

потоковый парсер на борту.

А у нас, вот пример (читаем 10 раз fopen и file_get_contents)

fread($handle, 1);

----filesize:   411009
----fread len: 1
Timing fopen: 60.1470 ms
Timing file_get_contents: 0.6912 ms
Timing fopen: 62.8970 ms
Timing file_get_contents: 0.3510 ms
Timing fopen: 56.3872 ms
Timing file_get_contents: 0.3788 ms
Timing fopen: 64.8222 ms
Timing file_get_contents: 0.3781 ms
Timing fopen: 59.4339 ms
Timing file_get_contents: 0.3750 ms
Timing fopen: 61.2819 ms
Timing file_get_contents: 0.3550 ms
Timing fopen: 55.8791 ms
Timing file_get_contents: 0.3731 ms
Timing fopen: 61.0499 ms
Timing file_get_contents: 0.3550 ms
Timing fopen: 53.5061 ms
Timing file_get_contents: 0.4139 ms
Timing fopen: 60.6580 ms
Timing file_get_contents: 0.3819 ms

fread($handle, 4096);

----filesize:   411009
----fread len: 4096
Timing fopen: 0.7210 ms
Timing file_get_contents: 0.5479 ms
Timing fopen: 0.3130 ms
Timing file_get_contents: 0.2179 ms
Timing fopen: 0.2880 ms
Timing file_get_contents: 0.2019 ms
Timing fopen: 0.2718 ms
Timing file_get_contents: 0.2241 ms
Timing fopen: 0.3440 ms
Timing file_get_contents: 0.2580 ms
Timing fopen: 0.3731 ms
Timing file_get_contents: 0.2759 ms
Timing fopen: 0.3359 ms
Timing file_get_contents: 0.2561 ms
Timing fopen: 0.3331 ms
Timing file_get_contents: 0.2730 ms
Timing fopen: 0.3619 ms
Timing file_get_contents: 0.2720 ms
Timing fopen: 0.3259 ms
Timing file_get_contents: 0.2201 ms

Но, если по 4096 или не суть там сколько, последний объект будет разорван и надо как то сохранять состояние. Хотя, тоже несложно просто посидеть надо.

------резюме

И да, на PHP все равно проиграем GO. Даже отыграв 60 от 140 ~ 80 сильно больше 22-x

DenisVS:
It must be some kind of wrapper, while all running scripts at once (in different languages) to compare.

From the point of view of a scientific experiment, the comparison methodology can, and it makes sense to think about. And in this sense the subject can no longer see. Danforth, won with a margin of 5-10 fold, but he and judging by the GO

func NewDecoderfunc NewDecoder (r io.Reader) * DecoderNewDecoder returns a new decoder that reads from r.The decoder introduces its own buffering and may read data from r beyond the JSON values requested.

streaming parser on board.

And we have here is an example (read 10 times fopen and file_get_contents)

fread ($ handle, 1);

 ---- filesize: 411009 
---- fread len: 1
Timing fopen: 60.1470 ms
Timing file_get_contents: 0.6912 ms
Timing fopen: 62.8970 ms
Timing file_get_contents: 0.3510 ms
Timing fopen: 56.3872 ms
Timing file_get_contents: 0.3788 ms
Timing fopen: 64.8222 ms
Timing file_get_contents: 0.3781 ms
Timing fopen: 59.4339 ms
Timing file_get_contents: 0.3750 ms
Timing fopen: 61.2819 ms
Timing file_get_contents: 0.3550 ms
Timing fopen: 55.8791 ms
Timing file_get_contents: 0.3731 ms
Timing fopen: 61.0499 ms
Timing file_get_contents: 0.3550 ms
Timing fopen: 53.5061 ms
Timing file_get_contents: 0.4139 ms
Timing fopen: 60.6580 ms
Timing file_get_contents: 0.3819 ms

fread ($ handle, 4096);

 ---- filesize: 411009 
---- fread len: 4096
Timing fopen: 0.7210 ms
Timing file_get_contents: 0.5479 ms
Timing fopen: 0.3130 ms
Timing file_get_contents: 0.2179 ms
Timing fopen: 0.2880 ms
Timing file_get_contents: 0.2019 ms
Timing fopen: 0.2718 ms
Timing file_get_contents: 0.2241 ms
Timing fopen: 0.3440 ms
Timing file_get_contents: 0.2580 ms
Timing fopen: 0.3731 ms
Timing file_get_contents: 0.2759 ms
Timing fopen: 0.3359 ms
Timing file_get_contents: 0.2561 ms
Timing fopen: 0.3331 ms
Timing file_get_contents: 0.2730 ms
Timing fopen: 0.3619 ms
Timing file_get_contents: 0.2720 ms
Timing fopen: 0.3259 ms
Timing file_get_contents: 0.2201 ms

But if 4096 or how many are there, the last object is broken and should be such as to save the state. Although too easy just need to sit down.

------summary

And yes, PHP will still lose GO. Even after playing 60 of 140 ~ 80 strongly over 22-x

Sly32:
Ты б еще мельче скрин выложил)

Там кликнуть можно

Sly32:
You'd even put smaller screen)

There you can click

danforth:
За сколько у вас отработал ваш код на данном файле?

Условия у всех разные. Для справедливой оценки на 1 машине все пускать надо.

У меня например, запускалось примерно в таких условиях

Danforth:
For how much you have worked for your code to this file?

Terms and conditions are different. For a fair assessment at all 1 machine should be allowed.

I for example, to run about in such conditions

VoV@:
ИМХО, только и перебором символов получится

Решения выше было со stream_get_line, пачкой символов до разделителя + preg_match. Чтение по одному символу позволяет проще решить задачу.

Особенно если чуть задачу усложнить. В json

[
  {

"id":2234,
"scores":{
"max":267,
"min":17
}
},
{
"id":2235,
"name":"OOOYO",
"price":200319.12,
"scores":{
"max":408,
"min":78
}
}
И надо найти scores.max, например более 500, при этом формат объектов гибкий

Чуть изменив код


$read=0;
......
if($c=='{'){
$read++;
}
if($read>0) {
$str.=$c;
}
if($c=='}') {
$read--;

задача легко решается

------------

danforth:
а можно задалбывать диск и ядро сисколами, читая по 1 байту.

Это да, конструктивное замечание, но за 20 мин сложно набросать рабочее. Мне по крайней мере.:(

png json-2.png
Всего: 541