Как быстро вывести массив целых чисел в консоль? - PullRequest
0 голосов
/ 18 августа 2010

У меня есть массив целых чисел

a = [1,2,3,4]

Когда я делаю

a.join

Руби внутренне вызывает метод to_s 4 раза, что слишком медленно для моих нужд.

Какой самый быстрый способ вывести большой массив целых чисел на консоль?

Я имею в виду:

a = [1,2,3,4........,1,2,3,9], should be: 

1234 ........ 1239

Ответы [ 5 ]

3 голосов
/ 18 августа 2010

Если вы хотите напечатать целое число в стандартный вывод, вам необходимо сначала преобразовать его в строку, так как это все, что понимает стандартный вывод. Если вы хотите вывести два целых числа в стандартный вывод, вам нужно сначала преобразовать их оба в строку. Если вы хотите вывести три целых числа в стандартный вывод, вам нужно сначала преобразовать все три в строку. Если вы хотите вывести один миллиард целых чисел на стандартный вывод, вам сначала нужно преобразовать один миллиард из них в строку.

Ты, мы, Ruby или любой другой язык программирования ничего не можем с этим поделать.

Вы можете попробовать чередовать преобразование с вводом / выводом, выполняя ленивую реализацию потока. Вы можете попытаться выполнить преобразование и ввод-вывод параллельно, выполнив ленивый поток и разделив преобразование и ввод-вывод на два отдельных потока. (Обязательно используйте реализацию Ruby, которая может на самом деле выполнять параллельные потоки, не все из них могут: MRI, YARV и Rubinius, например, не могут.)

Вы можете распараллелить преобразование, преобразовав отдельные куски в массиве в отдельные потоки параллельно. Вы даже можете купить миллиардный компьютер и одновременно конвертировать все миллиарды целых чисел одновременно.

Но даже тогда факт остается фактом: каждое целое число должно быть преобразовано. Делаете ли вы это один за другим сначала, а затем печатаете их или делаете это одно за другим с чередованием с вводом / выводом или делаете это один за другим параллельно с вводом / выводом или даже конвертируете их все в одно и то же время на миллиарде процессоров: количество необходимых преобразований не уменьшается. Большое количество целых чисел означает большое количество преобразований. Даже если вы выполняете все миллиарды преобразований в одном миллиардном центральном процессоре параллельно, это все же миллиардов преобразований, то есть миллиардов обращений к to_s.

2 голосов
/ 18 августа 2010

Как указано в комментариях выше, если Fixnum.to_s не выполняет достаточно быстро для вас, тогда вам действительно нужно подумать, является ли Ruby правильным инструментом для этой конкретной задачи.

Однако есть паравещи, которые вы могли бы сделать, могут или не могут быть применимы для вашей ситуации.

Если построение массива происходит за пределами критической по времени области, то создайте массив или скопируйте массив со строками вместо целых чисел.С моим небольшим тестом в 10000 целых чисел это примерно в 5 раз быстрее.

Если вы управляете процессом чтения и записи, используйте Array.pack для записи вывода и String.unpack для чтения результата.Это может быть не так быстро, поскольку пакет, похоже, вызывает Fixnum.to_int, даже если элементы уже являются целыми числами.

Я ожидаю, что эти цифры будут разными в каждой версии Ruby, поэтому стоит проверить вашу конкретную целевую версию.

0 голосов
/ 18 августа 2010

Если вам действительно не нужно видеть цифры на консоли (а это звучит так, как будто вы этого не делаете), то записывайте их в двоичный файл - должно быть намного быстрее.

И вы можете передавать двоичные файлы в другие программы, если это то, что вам нужно, а не просто текст.

0 голосов
/ 18 августа 2010

Для однозначных чисел вы можете сделать это

[1,2,3,4,5].map{|x|(x+48).chr}.join

Если вам нужно ускорить большее число, вы можете попытаться запомнить результат to_s

0 голосов
/ 18 августа 2010

Медлительность в вашей программе происходит не от to_s, вызываемой 4 раза, а от печати на консоль. Вывод на консоль медленный, и вы ничего не можете с этим поделать.

...