숫자 목록 목록의 요소를 문자로 바꾸는 가장 빠른 방법은 무엇입니까? 이 챌린지는 여기 커뮤니티에 있는 질문의 연장선입니다. 저는 8가지 접근 방식을 테스트하기로 결정했습니다. 세 가지 반복 방법( For , For Each 및 Transform Each ), 네 가지 비반복 방법(테이블 작업, 표현식, Words + 표현식 및 Regex ) 및 한 가지 혼합 방법( Words + Transform Each )입니다. 정규 표현식 이나 표현식을 포함하지 않는 이러한 방법 중 5개는 링크된 게시물에서 고려되었습니다. Words 와 Regex를 사용하는 방법은 문자열 작업의 부작용을 이용한다는 점에서 약간의 속임수입니다. 특히 모든 데이터 구조를 문자열로 변환하고 그에 따라 구문 분석할 수 있습니다. 이 접근 방식이 합법적이라고 생각하는지 여부는 독자에게 맡기겠습니다. 나는 그것에 대해 눈살을 찌푸릴 몇몇 사람들을 알고 있습니다!
공간 채우기 디자인을 사용하여 목록 수, 목록 요소 수, 목록의 요소 수가 같거나 같지 않은지 여부, 숫자 유형(정수 또는 부동 소수점)이라는 네 가지 요소를 살펴보았습니다. 디자인은 목록 목록 - Experimental Runs.JMP 에 있습니다. 원래 설계 세대의 분수 값은 반올림되었습니다. 각 실행마다 10번의 복제가 이루어졌습니다. 실험을 실행하는 데 사용한 코드는 Run list of listed Experiment.JSL 에 있고 결과는 List of list results.JMP에 있습니다. Regex를 사용한 예비 실행은 매우 느리므로 고려 대상에서 제외되었습니다.
방법을 비교하기 위해 실행 및 복제별로 각 방법의 순위 순서를 계산하고 실험 실행 내의 모든 복제에 대한 실행 시간과 중간 실행 시간 간의 차이를 계산합니다. 작을수록 좋습니다. 아래 그래프는 Transform Each , 테이블 작업 및 Words 방법이 우수했음을 나타냅니다. 실제 시간 차이는 작지만(값은 마이크로초 단위) 이러한 방법은 지속적으로 더 높은 순위를 차지하고 변동성이 적습니다.


네 가지 방법 간에 차이점이 있는지 확인하기 위해 더 큰 목록( List of list big - Experimental Runs.JMP 및 List of list big results.JMP )을 사용하여 실험을 다시 실행했습니다. 실행 내 평균 시간과의 시간 차이를 살펴보면 총 항목 수가 증가함에 따라 각각 변환 및 테이블 작업이 가장 잘 수행되는 것으로 보입니다. 이는 다행스러운 결과입니다. 각각 변환은 JMP 16 에서만 도입되었으며 테이블 작업은 여전히 JMP 15를 사용하는 사람들에게 좋은 솔루션을 제공하기 때문입니다.

두 번째 챌린지는 목록의 목록을 전치해 달라고 요청했습니다. 전치된 목록 목록은 입력 목록의 모든 첫 번째 요소를 첫 번째 출력 목록으로 수집하고, 두 번째 입력 요소를 두 번째 출력 목록으로 수집합니다. 입력에 n개의 목록이 있는 경우 각 출력 목록에는 n 개의 요소가 있습니다. 출력 목록의 수는 각 목록의 최대 항목 수와 같습니다. 입력 목록의 수는 결정하기 쉽지만 출력 목록의 수는 각 입력 목록의 항목 수를 계산해야 합니다. 이것이 필요한가? 더 빠른 프로세스로 이어지나요?
이 질문에 대답하고 특정 방법을 테스트하기 위해 공간을 채우는 또 다른 디자인을 실행했습니다. 여기서는 각각 두 가지 접근 방식을 사용하여 세 가지 반복 방법( For , For Each 및 Transform Each )을 살펴보았습니다. 하나는 출력을 작성하기 전에 출력 목록 수를 계산하고 입력을 두 번 반복해야 하며 다른 하나는 다음을 사용하여 출력을 작성합니다. 입력에 대한 단일 루프. 추가적으로 테이블 연산을 활용하는 방법도 살펴봤습니다. 6가지 다른 목록 요소 유형(정수, 부동 소수점, 1자, 8자, 15자, 가변 너비 문자(최대 길이 15))과 고정 및 가변(내부) 목록 길이가 고려되었습니다.
초기 코딩 중에 반복 또는 표현식을 사용하여 누락된 값으로 출력을 미리 채우는 것보다 빈 목록으로 시작하고 삽입을 사용하여 출력 목록을 작성하는 것이 더 빠르다는 것을 발견했습니다. Prebuild 또는 Insert.JSL 의 코드를 사용하여 직접 확인할 수 있습니다. 두 번째 발견은 Transform Each 및 For Each 와 관련이 있었습니다. 이러한 함수에 익숙하지 않은 경우 크기를 지정하지 않고도 목록, 행렬 또는 연관 배열을 반복할 수 있다는 점에서 표준 For 또는 While 루프와 약간 다르게 동작합니다. 이렇게 하면 코드가 좀 더 간결하고 깔끔해집니다. 이들 함수 중 하나에 대한 기본 호출 구조는 다음과 같습니다.
fnName ({ indValue , ind }, 컨테이너 , 본문 )
여기서 fnName 은 For Each 또는 Transform Each 이고, indValue 는 인덱스 ind 에 있는 컨테이너의 값이고, 컨테이너 는 행렬, 목록 또는 연관 배열이고, 본문 은 코드 본문입니다. 큰 용기를 다룰 때는 주의가 필요합니다. 대규모 데이터 구조를 컨테이너 또는 indValue 로 사용하면 실행 속도가 상당히 느려집니다. 이에 대한 예는 For Each 및 Transform Each.JSL 사용 에 나와 있습니다. 여기서는 목록 목록의 각 목록에 있는 항목 수를 계산합니다. 처음 두 코드 블록은 문제를 코딩할 것으로 예상되는 방식에 해당합니다. 첫 번째는 각 하위 목록을 입력 값으로 사용하고 두 번째는 하위 목록을 인덱싱합니다. 이것을 aList 에 대한 인덱스가 명시적으로 생성되어 루프에서 사용되는 세 번째 블록과 비교해 보세요. aList 의 크기에 따라 처리 속도가 100배 이상 향상될 수 있습니다. Transform Each 는 훨씬 더 빠르므로 결과 값을 반환할 수 있습니다. 블록 4와 5는 출력 데이터 구조가 입력 컨테이너에 사용되는 데이터 구조와 동일함을 보여줍니다. 출력 데이터 구조의 유형을 제어하는 선택적 Output() 인수가 있습니다.
다양한 전치 방법을 테스트하기 위한 코드는 Transpose listed.JSL 에 있습니다. 위와 같이 다양한 조건에서의 출력을 비교하기 위해 공간 채우기 설계를 사용했습니다. 위의 코드와는 달리, 반복될 때마다 새로운 데이터 구조가 생성됩니다. 처음 세 가지 방법은 입력을 읽고 단일 블록에 출력을 작성합니다. 다음 세 개는 입력을 처리하기 전에 먼저 출력 목록의 크기를 미리 결정합니다. 두 번째에서 마지막 방법은 테이블 작업을 사용했고 마지막 Transform Each는 출력 값을 사용하도록 구조화되었습니다.

출력 목록의 크기를 미리 결정하는 것이 단일 블록에서 이를 수행하려고 시도하는 것보다 빠른 것으로 입증되었습니다. Transform Each 의 다양한 구현은 출력 값을 사용하여 얻은 속도 향상을 보여줍니다. 결과는 Transpose results.JMP 에 있습니다. For Each , Transform Each (두 번째 구현) 및 테이블 작업을 비교하는 더 큰 목록을 사용한 실험은 Transpose 결과 big.JMP 에서 찾을 수 있습니다. 결과는 일반적으로 테이블 작업이 다른 두 가지 접근 방식보다 성능이 우수하다는 것을 시사합니다.

우리가 발견한 내용을 요약하자면:
- 시간별: Each < For Each < For
- 열 수식이 포함되지 않으면 테이블 작업이 매우 빨라질 수 있습니다. 이전 게시물에서 우리는 복잡성에 따라 열 수식이 반복이나 표현식이 적합한 지점까지 작업 속도를 늦출 수 있다는 것을 확인했습니다.
이 과제에 대해 과거에 받았던 일반적인 피드백을 얻지 못했기 때문에 더 나은 접근 방식이 있을 것이라고 확신합니다. 나는 당신의 의견을 듣고 싶습니다. 다음 달에는 새로운 도전을 찾아보세요.